Unreviewed, rolling out r205931.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Sep 2016 16:51:12 +0000 (16:51 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Sep 2016 16:51:12 +0000 (16:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162021

Tests for this change fail on 32-bit JSC bots (Requested by
ryanhaddad on #webkit).

Reverted changeset:

"[JSC] Make the rounding-related nodes support any type"
https://bugs.webkit.org/show_bug.cgi?id=161895
http://trac.webkit.org/changeset/205931

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205974 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
JSTests/ChangeLog
JSTests/stress/arith-ceil-on-various-types.js [deleted file]
JSTests/stress/arith-floor-on-various-types.js [deleted file]
JSTests/stress/arith-round-on-various-types.js [deleted file]
JSTests/stress/arith-trunc-on-various-types.js [deleted file]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

index abda5ce..776bff4 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-15  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205931.
+        https://bugs.webkit.org/show_bug.cgi?id=162021
+
+        Tests for this change fail on 32-bit JSC bots (Requested by
+        ryanhaddad on #webkit).
+
+        Reverted changeset:
+
+        "[JSC] Make the rounding-related nodes support any type"
+        https://bugs.webkit.org/show_bug.cgi?id=161895
+        http://trac.webkit.org/changeset/205931
+
 2016-09-15  Joseph Pecoraro  <pecoraro@apple.com>
 
         test262: Should be a SyntaxError for duplicate parameter names in function with default parameters
diff --git a/JSTests/stress/arith-ceil-on-various-types.js b/JSTests/stress/arith-ceil-on-various-types.js
deleted file mode 100644 (file)
index 95dd27d..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-"use strict";
-
-let validInputTestCases = [
-    // input as string, expected result as string.
-    ["undefined", "NaN"],
-    ["null", "0"],
-    ["0", "0"],
-    ["-0.", "-0"],
-    ["0.5", "1"],
-    ["-0.5", "-0"],
-    ["4", "4"],
-    ["42.1", "43"],
-    ["42.5", "43"],
-    ["42.9", "43"],
-    ["-42.1", "-42"],
-    ["-42.5", "-42"],
-    ["-42.9", "-42"],
-    ["Math.PI", "4"],
-    ["Infinity", "Infinity"],
-    ["-Infinity", "-Infinity"],
-    ["NaN", "NaN"],
-    ["\"WebKit\"", "NaN"],
-    ["\"4\"", "4"],
-    ["\"42.5\"", "43"],
-    ["{ valueOf: () => { return 4; } }", "4"],
-    ["{ valueOf: () => { return 0; } }", "0"],
-    ["{ valueOf: () => { return -0; } }", "-0"],
-    ["{ valueOf: () => { return 0.5; } }", "1"],
-    ["{ valueOf: () => { return -0.5; } }", "-0"],
-    ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
-    ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
-    ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
-    ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
-    ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
-    ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483648"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
-    if (expected === expected) {
-        if (result !== expected)
-            return false;
-        if (!expected && (1 / expected) !== (1 / result))
-            return false;
-
-        return true;
-    }
-    return result !== result;
-}
-
-
-// Test Math.ceil() without arguments.
-function opaqueCeilNoArgument() {
-    return Math.ceil();
-}
-noInline(opaqueCeilNoArgument);
-noOSRExitFuzzing(opaqueCeilNoArgument);
-
-function testNoArgument() {
-    for (let i = 0; i < 1e4; ++i) {
-        let output = opaqueCeilNoArgument();
-        if (!isIdentical(output, NaN)) {
-            throw "Failed opaqueCeilNoArgument";
-        }
-    }
-    if (numberOfDFGCompiles(opaqueCeilNoArgument) > 1)
-        throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.ceil() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesCeil(argument) {
-    return Math.ceil(argument);
-}
-noInline(opaqueAllTypesCeil);
-noOSRExitFuzzing(opaqueAllTypesCeil);
-
-function testAllTypesCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesCeil(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1]))
-                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesCeil) > 3)
-        throw "We should have detected ceil() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesCeilWithoutNegativeZero(argument) {
-    return Math.ceil(argument) + 0;
-}
-noInline(opaqueAllTypesCeilWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesCeilWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesCeilWithoutNegativeZero(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1] + 0))
-                throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesCeil) > 3)
-        throw "We should have detected ceil() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.ceil() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueCeil(argument) {
-                return Math.ceil(argument);
-            }
-            noInline(opaqueCeil);
-            noOSRExitFuzzing(opaqueCeil);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueCeil(${testCaseInput[0]}), ${testCaseInput[1]})) {
-                    throw "Failed testSingleTypeCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueCeil) > 1)
-                throw "We should have compiled a single ceil for the expected type.";
-        `);
-    }
-}
-testSingleTypeCall();
-
-
-// Test Math.ceil() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueCeil(argument) {
-                return Math.ceil(argument) + 0;
-            }
-            noInline(opaqueCeil);
-            noOSRExitFuzzing(opaqueCeil);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueCeil(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
-                    throw "Failed testSingleTypeWithoutNegativeZeroCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueCeil) > 1)
-                throw "We should have compiled a single ceil for the expected type.";
-        `);
-    }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.ceil() on constants
-function testConstant() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueCeilOnConstant() {
-                return Math.ceil(${testCaseInput[0]});
-            }
-            noInline(opaqueCeilOnConstant);
-            noOSRExitFuzzing(opaqueCeilOnConstant);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueCeilOnConstant(), ${testCaseInput[1]})) {
-                    throw "Failed testConstant()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueCeilOnConstant) > 1)
-                throw "We should have compiled a single ceil for the expected type.";
-        `);
-    }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueCeilForSideEffects(argument) {
-    return Math.ceil(argument);
-}
-noInline(opaqueCeilForSideEffects);
-noOSRExitFuzzing(opaqueCeilForSideEffects);
-
-function testSideEffect() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let ceil16 = Math.ceil(16);
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueCeilForSideEffects(testObject) !== ceil16)
-            throw "Incorrect result in testSideEffect()";
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testSideEffect()";
-    if (numberOfDFGCompiles(opaqueCeilForSideEffects) > 1)
-        throw "opaqueCeilForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify ceil() is not subject to CSE if the argument has side effects.
-function opaqueCeilForCSE(argument) {
-    return Math.ceil(argument) + Math.ceil(argument) + Math.ceil(argument);
-}
-noInline(opaqueCeilForCSE);
-noOSRExitFuzzing(opaqueCeilForCSE);
-
-function testCSE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let ceil16 = Math.ceil(16);
-    let threeCeil16 = ceil16 + ceil16 + ceil16;
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueCeilForCSE(testObject) !== threeCeil16)
-            throw "Incorrect result in testCSE()";
-    }
-    if (testObject.counter !== 3e4)
-        throw "Failed testCSE()";
-    if (numberOfDFGCompiles(opaqueCeilForCSE) > 1)
-        throw "opaqueCeilForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify ceil() is not subject to DCE if the argument has side effects.
-function opaqueCeilForDCE(argument) {
-    Math.ceil(argument);
-}
-noInline(opaqueCeilForDCE);
-noOSRExitFuzzing(opaqueCeilForDCE);
-
-function testDCE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    for (let i = 0; i < 1e4; ++i) {
-        opaqueCeilForDCE(testObject);
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testDCE()";
-    if (numberOfDFGCompiles(opaqueCeilForDCE) > 1)
-        throw "opaqueCeilForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
-    let counter = 0;
-    function opaqueCeilWithException(argument) {
-        let result = Math.ceil(argument);
-        ++counter;
-        return result;
-    }
-    noInline(opaqueCeilWithException);
-
-    let testObject = { valueOf: () => {  return 64; } };
-    let ceil64 = Math.ceil(64);
-
-    // Warm up without exception.
-    for (let i = 0; i < 1e3; ++i) {
-        if (opaqueCeilWithException(testObject) !== ceil64)
-            throw "Incorrect result in opaqueCeilWithException()";
-    }
-
-    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
-    for (let i = 0; i < 1e2; ++i) {
-        try {
-            if (opaqueCeilWithException(testThrowObject) !== 8)
-                throw "This code should not be reached!!";
-        } catch (e) {
-            if (e !== testObject) {
-                throw "Wrong object thrown from opaqueCeilWithException."
-            }
-        }
-    }
-
-    if (counter !== 1e3) {
-        throw "Invalid count in testException()";
-    }
-}
-testException();
diff --git a/JSTests/stress/arith-floor-on-various-types.js b/JSTests/stress/arith-floor-on-various-types.js
deleted file mode 100644 (file)
index b2f360c..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-"use strict";
-
-let validInputTestCases = [
-    // input as string, expected result as string.
-    ["undefined", "NaN"],
-    ["null", "0"],
-    ["0", "0"],
-    ["-0.", "-0"],
-    ["0.5", "0"],
-    ["-0.5", "-1"],
-    ["4", "4"],
-    ["42.1", "42"],
-    ["42.5", "42"],
-    ["42.9", "42"],
-    ["-42.1", "-43"],
-    ["-42.5", "-43"],
-    ["-42.9", "-43"],
-    ["Math.PI", "3"],
-    ["Infinity", "Infinity"],
-    ["-Infinity", "-Infinity"],
-    ["NaN", "NaN"],
-    ["\"WebKit\"", "NaN"],
-    ["\"4\"", "4"],
-    ["\"42.5\"", "42"],
-    ["{ valueOf: () => { return 4; } }", "4"],
-    ["{ valueOf: () => { return 0; } }", "0"],
-    ["{ valueOf: () => { return -0; } }", "-0"],
-    ["{ valueOf: () => { return 0.5; } }", "0"],
-    ["{ valueOf: () => { return -0.5; } }", "-1"],
-    ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
-    ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
-    ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
-    ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
-    ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483649"],
-    ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483647"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
-    if (expected === expected) {
-        if (result !== expected)
-            return false;
-        if (!expected && (1 / expected) !== (1 / result))
-            return false;
-
-        return true;
-    }
-    return result !== result;
-}
-
-
-// Test Math.floor() without arguments.
-function opaqueFloorNoArgument() {
-    return Math.floor();
-}
-noInline(opaqueFloorNoArgument);
-noOSRExitFuzzing(opaqueFloorNoArgument);
-
-function testNoArgument() {
-    for (let i = 0; i < 1e4; ++i) {
-        let output = opaqueFloorNoArgument();
-        if (!isIdentical(output, NaN)) {
-            throw "Failed opaqueFloorNoArgument";
-        }
-    }
-    if (numberOfDFGCompiles(opaqueFloorNoArgument) > 1)
-        throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.floor() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesFloor(argument) {
-    return Math.floor(argument);
-}
-noInline(opaqueAllTypesFloor);
-noOSRExitFuzzing(opaqueAllTypesFloor);
-
-function testAllTypesCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesFloor(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1]))
-                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesFloor) > 3)
-        throw "We should have detected floor() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesFloorWithoutNegativeZero(argument) {
-    return Math.floor(argument) + 0;
-}
-noInline(opaqueAllTypesFloorWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesFloorWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesFloorWithoutNegativeZero(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1] + 0))
-                throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesFloor) > 3)
-        throw "We should have detected floor() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.floor() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueFloor(argument) {
-                return Math.floor(argument);
-            }
-            noInline(opaqueFloor);
-            noOSRExitFuzzing(opaqueFloor);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueFloor(${testCaseInput[0]}), ${testCaseInput[1]})) {
-                    throw "Failed testSingleTypeCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueFloor) > 1)
-                throw "We should have compiled a single floor for the expected type.";
-        `);
-    }
-}
-testSingleTypeCall();
-
-
-// Test Math.floor() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueFloor(argument) {
-                return Math.floor(argument) + 0;
-            }
-            noInline(opaqueFloor);
-            noOSRExitFuzzing(opaqueFloor);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueFloor(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
-                    throw "Failed testSingleTypeWithoutNegativeZeroCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueFloor) > 1)
-                throw "We should have compiled a single floor for the expected type.";
-        `);
-    }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.floor() on constants
-function testConstant() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueFloorOnConstant() {
-                return Math.floor(${testCaseInput[0]});
-            }
-            noInline(opaqueFloorOnConstant);
-            noOSRExitFuzzing(opaqueFloorOnConstant);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueFloorOnConstant(), ${testCaseInput[1]})) {
-                    throw "Failed testConstant()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueFloorOnConstant) > 1)
-                throw "We should have compiled a single floor for the expected type.";
-        `);
-    }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueFloorForSideEffects(argument) {
-    return Math.floor(argument);
-}
-noInline(opaqueFloorForSideEffects);
-noOSRExitFuzzing(opaqueFloorForSideEffects);
-
-function testSideEffect() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let floor16 = Math.floor(16);
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueFloorForSideEffects(testObject) !== floor16)
-            throw "Incorrect result in testSideEffect()";
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testSideEffect()";
-    if (numberOfDFGCompiles(opaqueFloorForSideEffects) > 1)
-        throw "opaqueFloorForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify floor() is not subject to CSE if the argument has side effects.
-function opaqueFloorForCSE(argument) {
-    return Math.floor(argument) + Math.floor(argument) + Math.floor(argument);
-}
-noInline(opaqueFloorForCSE);
-noOSRExitFuzzing(opaqueFloorForCSE);
-
-function testCSE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let floor16 = Math.floor(16);
-    let threeFloor16 = floor16 + floor16 + floor16;
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueFloorForCSE(testObject) !== threeFloor16)
-            throw "Incorrect result in testCSE()";
-    }
-    if (testObject.counter !== 3e4)
-        throw "Failed testCSE()";
-    if (numberOfDFGCompiles(opaqueFloorForCSE) > 1)
-        throw "opaqueFloorForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify floor() is not subject to DCE if the argument has side effects.
-function opaqueFloorForDCE(argument) {
-    Math.floor(argument);
-}
-noInline(opaqueFloorForDCE);
-noOSRExitFuzzing(opaqueFloorForDCE);
-
-function testDCE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    for (let i = 0; i < 1e4; ++i) {
-        opaqueFloorForDCE(testObject);
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testDCE()";
-    if (numberOfDFGCompiles(opaqueFloorForDCE) > 1)
-        throw "opaqueFloorForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
-    let counter = 0;
-    function opaqueFloorWithException(argument) {
-        let result = Math.floor(argument);
-        ++counter;
-        return result;
-    }
-    noInline(opaqueFloorWithException);
-
-    let testObject = { valueOf: () => {  return 64; } };
-    let floor64 = Math.floor(64);
-
-    // Warm up without exception.
-    for (let i = 0; i < 1e3; ++i) {
-        if (opaqueFloorWithException(testObject) !== floor64)
-            throw "Incorrect result in opaqueFloorWithException()";
-    }
-
-    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
-    for (let i = 0; i < 1e2; ++i) {
-        try {
-            if (opaqueFloorWithException(testThrowObject) !== 8)
-                throw "This code should not be reached!!";
-        } catch (e) {
-            if (e !== testObject) {
-                throw "Wrong object thrown from opaqueFloorWithException."
-            }
-        }
-    }
-
-    if (counter !== 1e3) {
-        throw "Invalid count in testException()";
-    }
-}
-testException();
diff --git a/JSTests/stress/arith-round-on-various-types.js b/JSTests/stress/arith-round-on-various-types.js
deleted file mode 100644 (file)
index 371921b..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-"use strict";
-
-let validInputTestCases = [
-    // input as string, expected result as string.
-    ["undefined", "NaN"],
-    ["null", "0"],
-    ["0", "0"],
-    ["-0.", "-0"],
-    ["0.5", "1"],
-    ["-0.5", "-0"],
-    ["4", "4"],
-    ["42.1", "42"],
-    ["42.5", "43"],
-    ["42.9", "43"],
-    ["-42.1", "-42"],
-    ["-42.5", "-42"],
-    ["-42.9", "-43"],
-    ["Math.PI", "3"],
-    ["Infinity", "Infinity"],
-    ["-Infinity", "-Infinity"],
-    ["NaN", "NaN"],
-    ["\"WebKit\"", "NaN"],
-    ["\"4\"", "4"],
-    ["\"42.5\"", "43"],
-    ["{ valueOf: () => { return 4; } }", "4"],
-    ["{ valueOf: () => { return 0; } }", "0"],
-    ["{ valueOf: () => { return -0; } }", "-0"],
-    ["{ valueOf: () => { return 0.5; } }", "1"],
-    ["{ valueOf: () => { return -0.5; } }", "-0"],
-    ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
-    ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
-    ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
-    ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
-    ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
-    ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483648"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
-    if (expected === expected) {
-        if (result !== expected)
-            return false;
-        if (!expected && (1 / expected) !== (1 / result))
-            return false;
-
-        return true;
-    }
-    return result !== result;
-}
-
-
-// Test Math.round() without arguments.
-function opaqueRoundNoArgument() {
-    return Math.round();
-}
-noInline(opaqueRoundNoArgument);
-noOSRExitFuzzing(opaqueRoundNoArgument);
-
-function testNoArgument() {
-    for (let i = 0; i < 1e4; ++i) {
-        let output = opaqueRoundNoArgument();
-        if (!isIdentical(output, NaN)) {
-            throw "Failed opaqueRoundNoArgument";
-        }
-    }
-    if (numberOfDFGCompiles(opaqueRoundNoArgument) > 1)
-        throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.round() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesRound(argument) {
-    return Math.round(argument);
-}
-noInline(opaqueAllTypesRound);
-noOSRExitFuzzing(opaqueAllTypesRound);
-
-function testAllTypesCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesRound(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1]))
-                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesRound) > 3)
-        throw "We should have detected round() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesRoundWithoutNegativeZero(argument) {
-    return Math.round(argument) + 0;
-}
-noInline(opaqueAllTypesRoundWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesRoundWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesRoundWithoutNegativeZero(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1] + 0))
-                throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesRound) > 3)
-        throw "We should have detected round() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.round() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueRound(argument) {
-                return Math.round(argument);
-            }
-            noInline(opaqueRound);
-            noOSRExitFuzzing(opaqueRound);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueRound(${testCaseInput[0]}), ${testCaseInput[1]})) {
-                    throw "Failed testSingleTypeCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueRound) > 1)
-                throw "We should have compiled a single round for the expected type.";
-        `);
-    }
-}
-testSingleTypeCall();
-
-
-// Test Math.round() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueRound(argument) {
-                return Math.round(argument) + 0;
-            }
-            noInline(opaqueRound);
-            noOSRExitFuzzing(opaqueRound);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueRound(${testCaseInput[0]}), ${testCaseInput[1]} + 0)) {
-                    throw "Failed testSingleTypeWithoutNegativeZeroCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueRound) > 1)
-                throw "We should have compiled a single round for the expected type.";
-        `);
-    }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.round() on constants
-function testConstant() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueRoundOnConstant() {
-                return Math.round(${testCaseInput[0]});
-            }
-            noInline(opaqueRoundOnConstant);
-            noOSRExitFuzzing(opaqueRoundOnConstant);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueRoundOnConstant(), ${testCaseInput[1]})) {
-                    throw "Failed testConstant()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueRoundOnConstant) > 1)
-                throw "We should have compiled a single round for the expected type.";
-        `);
-    }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueRoundForSideEffects(argument) {
-    return Math.round(argument);
-}
-noInline(opaqueRoundForSideEffects);
-noOSRExitFuzzing(opaqueRoundForSideEffects);
-
-function testSideEffect() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let round16 = Math.round(16);
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueRoundForSideEffects(testObject) !== round16)
-            throw "Incorrect result in testSideEffect()";
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testSideEffect()";
-    if (numberOfDFGCompiles(opaqueRoundForSideEffects) > 1)
-        throw "opaqueRoundForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify round() is not subject to CSE if the argument has side effects.
-function opaqueRoundForCSE(argument) {
-    return Math.round(argument) + Math.round(argument) + Math.round(argument);
-}
-noInline(opaqueRoundForCSE);
-noOSRExitFuzzing(opaqueRoundForCSE);
-
-function testCSE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let round16 = Math.round(16);
-    let threeRound16 = round16 + round16 + round16;
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueRoundForCSE(testObject) !== threeRound16)
-            throw "Incorrect result in testCSE()";
-    }
-    if (testObject.counter !== 3e4)
-        throw "Failed testCSE()";
-    if (numberOfDFGCompiles(opaqueRoundForCSE) > 1)
-        throw "opaqueRoundForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify round() is not subject to DCE if the argument has side effects.
-function opaqueRoundForDCE(argument) {
-    Math.round(argument);
-}
-noInline(opaqueRoundForDCE);
-noOSRExitFuzzing(opaqueRoundForDCE);
-
-function testDCE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    for (let i = 0; i < 1e4; ++i) {
-        opaqueRoundForDCE(testObject);
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testDCE()";
-    if (numberOfDFGCompiles(opaqueRoundForDCE) > 1)
-        throw "opaqueRoundForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
-    let counter = 0;
-    function opaqueRoundWithException(argument) {
-        let result = Math.round(argument);
-        ++counter;
-        return result;
-    }
-    noInline(opaqueRoundWithException);
-
-    let testObject = { valueOf: () => {  return 64; } };
-    let round64 = Math.round(64);
-
-    // Warm up without exception.
-    for (let i = 0; i < 1e3; ++i) {
-        if (opaqueRoundWithException(testObject) !== round64)
-            throw "Incorrect result in opaqueRoundWithException()";
-    }
-
-    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
-    for (let i = 0; i < 1e2; ++i) {
-        try {
-            if (opaqueRoundWithException(testThrowObject) !== 8)
-                throw "This code should not be reached!!";
-        } catch (e) {
-            if (e !== testObject) {
-                throw "Wrong object thrown from opaqueRoundWithException."
-            }
-        }
-    }
-
-    if (counter !== 1e3) {
-        throw "Invalid count in testException()";
-    }
-}
-testException();
diff --git a/JSTests/stress/arith-trunc-on-various-types.js b/JSTests/stress/arith-trunc-on-various-types.js
deleted file mode 100644 (file)
index 54c535b..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-"use strict";
-
-let validInputTestCases = [
-    // input as string, expected result as string.
-    ["undefined", "NaN"],
-    ["null", "0"],
-    ["0", "0"],
-    ["-0.", "-0"],
-    ["0.5", "0"],
-    ["-0.5", "-0"],
-    ["4", "4"],
-    ["42.1", "42"],
-    ["42.5", "42"],
-    ["42.9", "42"],
-    ["-42.1", "-42"],
-    ["-42.5", "-42"],
-    ["-42.9", "-42"],
-    ["Math.PI", "3"],
-    ["Infinity", "Infinity"],
-    ["-Infinity", "-Infinity"],
-    ["NaN", "NaN"],
-    ["\"WebKit\"", "NaN"],
-    ["\"4\"", "4"],
-    ["\"42.5\"", "42"],
-    ["{ valueOf: () => { return 4; } }", "4"],
-    ["{ valueOf: () => { return 0; } }", "0"],
-    ["{ valueOf: () => { return -0; } }", "-0"],
-    ["{ valueOf: () => { return 0.5; } }", "0"],
-    ["{ valueOf: () => { return -0.5; } }", "-0"],
-    ["{ valueOf: () => { return Number.MIN_SAFE_INTEGER; } }", "-9007199254740991"],
-    ["{ valueOf: () => { return Number.MAX_SAFE_INTEGER; } }", "9007199254740991"],
-    ["{ valueOf: () => { return 0x80000000|0; } }", "-2147483648"],
-    ["{ valueOf: () => { return 0x7fffffff|0; } }", "2147483647"],
-    ["{ valueOf: () => { return (0x80000000|0) - 0.5; } }", "-2147483648"],
-    ["{ valueOf: () => { return (0x7fffffff|0) + 0.5; } }", "2147483647"],
-];
-
-let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
-
-function isIdentical(result, expected)
-{
-    if (expected === expected) {
-        if (result !== expected)
-            return false;
-        if (!expected && (1 / expected) !== (1 / result))
-            return false;
-
-        return true;
-    }
-    return result !== result;
-}
-
-
-// Test Math.trunc() without arguments.
-function opaqueTruncNoArgument() {
-    return Math.trunc();
-}
-noInline(opaqueTruncNoArgument);
-noOSRExitFuzzing(opaqueTruncNoArgument);
-
-function testNoArgument() {
-    for (let i = 0; i < 1e4; ++i) {
-        let output = opaqueTruncNoArgument();
-        if (!isIdentical(output, NaN)) {
-            throw "Failed opaqueTruncNoArgument";
-        }
-    }
-    if (numberOfDFGCompiles(opaqueTruncNoArgument) > 1)
-        throw "The call without arguments should never exit.";
-}
-testNoArgument();
-
-
-// Test Math.trunc() with a very polymorphic input. All test cases are seen at each iteration.
-function opaqueAllTypesTrunc(argument) {
-    return Math.trunc(argument);
-}
-noInline(opaqueAllTypesTrunc);
-noOSRExitFuzzing(opaqueAllTypesTrunc);
-
-function testAllTypesCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesTrunc(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1]))
-                throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesTrunc) > 3)
-        throw "We should have detected trunc() was polymorphic and generated a generic version.";
-}
-testAllTypesCall();
-
-
-// Polymorphic input but negative zero is not observable.
-function opaqueAllTypesTruncWithoutNegativeZero(argument) {
-    return Math.trunc(argument) + 0;
-}
-noInline(opaqueAllTypesTruncWithoutNegativeZero);
-noOSRExitFuzzing(opaqueAllTypesTruncWithoutNegativeZero);
-
-function testAllTypesWithoutNegativeZeroCall() {
-    for (let i = 0; i < 1e3; ++i) {
-        for (let testCaseInput of validInputTypedTestCases) {
-            let output = opaqueAllTypesTruncWithoutNegativeZero(testCaseInput[0]);
-            if (!isIdentical(output, testCaseInput[1] + 0))
-                throw "Failed testAllTypesWithoutNegativeZeroCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
-        }
-    }
-    if (numberOfDFGCompiles(opaqueAllTypesTrunc) > 3)
-        throw "We should have detected trunc() was polymorphic and generated a generic version.";
-}
-testAllTypesWithoutNegativeZeroCall();
-
-
-// Test Math.trunc() on a completely typed input. Every call see only one type.
-function testSingleTypeCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueTrunc(argument) {
-                return Math.trunc(argument);
-            }
-            noInline(opaqueTrunc);
-            noOSRExitFuzzing(opaqueTrunc);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueTrunc(${testCaseInput[0]}), ${testCaseInput[1]})) {
-                    throw "Failed testSingleTypeCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueTrunc) > 1)
-                throw "We should have compiled a single trunc for the expected type.";
-        `);
-    }
-}
-testSingleTypeCall();
-
-
-// Test Math.trunc() on a completely typed input, but without negative zero.
-function testSingleTypeWithoutNegativeZeroCall() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueTrunc(argument) {
-                return Math.trunc(argument) - 0;
-            }
-            noInline(opaqueTrunc);
-            noOSRExitFuzzing(opaqueTrunc);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueTrunc(${testCaseInput[0]}), ${testCaseInput[1]} - 0)) {
-                    throw "Failed testSingleTypeWithoutNegativeZeroCall()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueTrunc) > 1)
-                throw "We should have compiled a single trunc for the expected type.";
-        `);
-    }
-}
-testSingleTypeWithoutNegativeZeroCall();
-
-
-// Test Math.trunc() on constants
-function testConstant() {
-    for (let testCaseInput of validInputTestCases) {
-        eval(`
-            function opaqueTruncOnConstant() {
-                return Math.trunc(${testCaseInput[0]});
-            }
-            noInline(opaqueTruncOnConstant);
-            noOSRExitFuzzing(opaqueTruncOnConstant);
-
-            for (let i = 0; i < 1e4; ++i) {
-                if (!isIdentical(opaqueTruncOnConstant(), ${testCaseInput[1]})) {
-                    throw "Failed testConstant()";
-                }
-            }
-            if (numberOfDFGCompiles(opaqueTruncOnConstant) > 1)
-                throw "We should have compiled a single trunc for the expected type.";
-        `);
-    }
-}
-testConstant();
-
-
-// Verify we call valueOf() exactly once per call.
-function opaqueTruncForSideEffects(argument) {
-    return Math.trunc(argument);
-}
-noInline(opaqueTruncForSideEffects);
-noOSRExitFuzzing(opaqueTruncForSideEffects);
-
-function testSideEffect() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let trunc16 = Math.trunc(16);
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueTruncForSideEffects(testObject) !== trunc16)
-            throw "Incorrect result in testSideEffect()";
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testSideEffect()";
-    if (numberOfDFGCompiles(opaqueTruncForSideEffects) > 1)
-        throw "opaqueTruncForSideEffects() is predictable, it should only be compiled once.";
-}
-testSideEffect();
-
-
-// Verify trunc() is not subject to CSE if the argument has side effects.
-function opaqueTruncForCSE(argument) {
-    return Math.trunc(argument) + Math.trunc(argument) + Math.trunc(argument);
-}
-noInline(opaqueTruncForCSE);
-noOSRExitFuzzing(opaqueTruncForCSE);
-
-function testCSE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    let trunc16 = Math.trunc(16);
-    let threeTrunc16 = trunc16 + trunc16 + trunc16;
-    for (let i = 0; i < 1e4; ++i) {
-        if (opaqueTruncForCSE(testObject) !== threeTrunc16)
-            throw "Incorrect result in testCSE()";
-    }
-    if (testObject.counter !== 3e4)
-        throw "Failed testCSE()";
-    if (numberOfDFGCompiles(opaqueTruncForCSE) > 1)
-        throw "opaqueTruncForCSE() is predictable, it should only be compiled once.";
-}
-testCSE();
-
-
-// Verify trunc() is not subject to DCE if the argument has side effects.
-function opaqueTruncForDCE(argument) {
-    Math.trunc(argument);
-}
-noInline(opaqueTruncForDCE);
-noOSRExitFuzzing(opaqueTruncForDCE);
-
-function testDCE() {
-    let testObject = {
-        counter: 0,
-        valueOf: function() { ++this.counter; return 16; }
-    };
-    for (let i = 0; i < 1e4; ++i) {
-        opaqueTruncForDCE(testObject);
-    }
-    if (testObject.counter !== 1e4)
-        throw "Failed testDCE()";
-    if (numberOfDFGCompiles(opaqueTruncForDCE) > 1)
-        throw "opaqueTruncForDCE() is predictable, it should only be compiled once.";
-}
-testDCE();
-
-
-// Test exceptions in the argument.
-function testException() {
-    let counter = 0;
-    function opaqueTruncWithException(argument) {
-        let result = Math.trunc(argument);
-        ++counter;
-        return result;
-    }
-    noInline(opaqueTruncWithException);
-
-    let testObject = { valueOf: () => {  return 64; } };
-    let trunc64 = Math.trunc(64);
-
-    // Warm up without exception.
-    for (let i = 0; i < 1e3; ++i) {
-        if (opaqueTruncWithException(testObject) !== trunc64)
-            throw "Incorrect result in opaqueTruncWithException()";
-    }
-
-    let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
-
-    for (let i = 0; i < 1e2; ++i) {
-        try {
-            if (opaqueTruncWithException(testThrowObject) !== 8)
-                throw "This code should not be reached!!";
-        } catch (e) {
-            if (e !== testObject) {
-                throw "Wrong object thrown from opaqueTruncWithException."
-            }
-        }
-    }
-
-    if (counter !== 1e3) {
-        throw "Invalid count in testException()";
-    }
-}
-testException();
index ffab282..bc52763 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-15  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r205931.
+        https://bugs.webkit.org/show_bug.cgi?id=162021
+
+        Tests for this change fail on 32-bit JSC bots (Requested by
+        ryanhaddad on #webkit).
+
+        Reverted changeset:
+
+        "[JSC] Make the rounding-related nodes support any type"
+        https://bugs.webkit.org/show_bug.cgi?id=161895
+        http://trac.webkit.org/changeset/205931
+
 2016-09-15  Joseph Pecoraro  <pecoraro@apple.com>
 
         test262: Should be a SyntaxError for duplicate parameter names in function with default parameters
index 218d5d9..e7af071 100644 (file)
@@ -905,23 +905,19 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     case ArithCeil:
     case ArithTrunc: {
         JSValue operand = forNode(node->child1()).value();
-        if (Optional<double> number = operand.toNumberFromPrimitive()) {
+        if (operand && operand.isNumber()) {
             double roundedValue = 0;
             if (node->op() == ArithRound)
-                roundedValue = jsRound(*number);
+                roundedValue = jsRound(operand.asNumber());
             else if (node->op() == ArithFloor)
-                roundedValue = floor(*number);
+                roundedValue = floor(operand.asNumber());
             else if (node->op() == ArithCeil)
-                roundedValue = ceil(*number);
+                roundedValue = ceil(operand.asNumber());
             else {
                 ASSERT(node->op() == ArithTrunc);
-                roundedValue = trunc(*number);
+                roundedValue = trunc(operand.asNumber());
             }
 
-            if (node->child1().useKind() == UntypedUse) {
-                setConstant(node, jsNumber(roundedValue));
-                break;
-            }
             if (producesInteger(node->arithRoundingMode())) {
                 int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
                 if (roundedValueAsInt32 == roundedValue) {
@@ -940,15 +936,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                 break;
             }
         }
-        if (node->child1().useKind() == DoubleRepUse) {
-            if (producesInteger(node->arithRoundingMode()))
-                forNode(node).setType(SpecInt32Only);
-            else if (node->child1().useKind() == DoubleRepUse)
-                forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
-        } else {
-            DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse);
-            forNode(node).setType(SpecFullNumber);
-        }
+        if (producesInteger(node->arithRoundingMode()))
+            forNode(node).setType(SpecInt32Only);
+        else
+            forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
         break;
     }
             
index 0b0d2dd..80a1c2e 100644 (file)
@@ -2450,22 +2450,25 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin
             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
             return true;
         }
-        insertChecks();
-        Node* operand = get(virtualRegisterForArgument(1, registerOffset));
-        NodeType op;
-        if (intrinsic == RoundIntrinsic)
-            op = ArithRound;
-        else if (intrinsic == FloorIntrinsic)
-            op = ArithFloor;
-        else if (intrinsic == CeilIntrinsic)
-            op = ArithCeil;
-        else {
-            ASSERT(intrinsic == TruncIntrinsic);
-            op = ArithTrunc;
+        if (argumentCountIncludingThis == 2) {
+            insertChecks();
+            Node* operand = get(virtualRegisterForArgument(1, registerOffset));
+            NodeType op;
+            if (intrinsic == RoundIntrinsic)
+                op = ArithRound;
+            else if (intrinsic == FloorIntrinsic)
+                op = ArithFloor;
+            else if (intrinsic == CeilIntrinsic)
+                op = ArithCeil;
+            else {
+                ASSERT(intrinsic == TruncIntrinsic);
+                op = ArithTrunc;
+            }
+            Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
+            set(VirtualRegister(resultOperand), roundNode);
+            return true;
         }
-        Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
-        set(VirtualRegister(resultOperand), roundNode);
-        return true;
+        return false;
     }
     case IMulIntrinsic: {
         if (argumentCountIncludingThis != 3)
index 04f3d12..55db094 100644 (file)
@@ -358,12 +358,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
     case ArithFloor:
     case ArithCeil:
     case ArithTrunc:
-        if (node->child1().useKind() == DoubleRepUse)
-            def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
-        else {
-            read(World);
-            write(Heap);
-        }
+        def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
         return;
 
     case CheckCell:
index 50f36c7..27a0f30 100644 (file)
@@ -376,28 +376,24 @@ private:
         case ArithFloor:
         case ArithCeil:
         case ArithTrunc: {
-            if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
+            if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
                 fixIntOrBooleanEdge(node->child1());
                 insertCheck<Int32Use>(m_indexInBlock, node->child1().node());
                 node->convertToIdentity();
                 break;
             }
-            if (node->child1()->shouldSpeculateNotCell()) {
-                fixDoubleOrBooleanEdge(node->child1());
+            fixDoubleOrBooleanEdge(node->child1());
 
-                if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
-                    node->setResult(NodeResultInt32);
-                    if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
-                        node->setArithRoundingMode(Arith::RoundingMode::Int32);
-                    else
-                        node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
-                } else {
-                    node->setResult(NodeResultDouble);
-                    node->setArithRoundingMode(Arith::RoundingMode::Double);
-                }
-                node->clearFlags(NodeMustGenerate);
-            } else
-                fixEdge<UntypedUse>(node->child1());
+            if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
+                node->setResult(NodeResultInt32);
+                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+                    node->setArithRoundingMode(Arith::RoundingMode::Int32);
+                else
+                    node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
+            } else {
+                node->setResult(NodeResultDouble);
+                node->setArithRoundingMode(Arith::RoundingMode::Double);
+            }
             break;
         }
 
index ffe41e7..dca1ca5 100644 (file)
@@ -155,10 +155,10 @@ namespace JSC { namespace DFG {
     macro(ArithFRound, NodeResultDouble | NodeMustGenerate) \
     macro(ArithPow, NodeResultDouble) \
     macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
-    macro(ArithRound, NodeResultNumber | NodeMustGenerate) \
-    macro(ArithFloor, NodeResultNumber | NodeMustGenerate) \
-    macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
-    macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithRound, NodeResultNumber) \
+    macro(ArithFloor, NodeResultNumber) \
+    macro(ArithCeil, NodeResultNumber) \
+    macro(ArithTrunc, NodeResultNumber) \
     macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
     macro(ArithSin, NodeResultDouble | NodeMustGenerate) \
     macro(ArithCos, NodeResultDouble | NodeMustGenerate) \
index ce546eb..562c8a4 100644 (file)
@@ -442,58 +442,6 @@ double JIT_OPERATION operationArithTan(ExecState* exec, EncodedJSValue encodedOp
     return tan(a);
 }
 
-EncodedJSValue JIT_OPERATION operationArithRound(ExecState* exec, EncodedJSValue encodedArgument)
-{
-    VM* vm = &exec->vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(*vm);
-
-    JSValue argument = JSValue::decode(encodedArgument);
-    double valueOfArgument = argument.toNumber(exec);
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    return JSValue::encode(jsNumber(jsRound(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithFloor(ExecState* exec, EncodedJSValue encodedArgument)
-{
-    VM* vm = &exec->vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(*vm);
-
-    JSValue argument = JSValue::decode(encodedArgument);
-    double valueOfArgument = argument.toNumber(exec);
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    return JSValue::encode(jsNumber(floor(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithCeil(ExecState* exec, EncodedJSValue encodedArgument)
-{
-    VM* vm = &exec->vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(*vm);
-
-    JSValue argument = JSValue::decode(encodedArgument);
-    double valueOfArgument = argument.toNumber(exec);
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    return JSValue::encode(jsNumber(ceil(valueOfArgument)));
-}
-
-EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState* exec, EncodedJSValue encodedArgument)
-{
-    VM* vm = &exec->vm();
-    NativeCallFrameTracer tracer(vm, exec);
-    auto scope = DECLARE_THROW_SCOPE(*vm);
-
-    JSValue argument = JSValue::decode(encodedArgument);
-    double truncatedValueOfArgument = argument.toIntegerPreserveNaN(exec);
-    if (UNLIKELY(scope.exception()))
-        return JSValue::encode(JSValue());
-    return JSValue::encode(jsNumber(truncatedValueOfArgument));
-}
-
 static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
 {
     VM& vm = exec->vm();
index 6ab7675..86e191e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -61,10 +61,6 @@ double JIT_OPERATION operationArithFRound(ExecState*, EncodedJSValue encodedOp1)
 double JIT_OPERATION operationArithLog(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
 double JIT_OPERATION operationArithSin(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
 double JIT_OPERATION operationArithSqrt(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithRound(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithFloor(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithCeil(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationArithTrunc(ExecState*, EncodedJSValue) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState*, JSCell*, EncodedJSValue encodedProperty) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState*, JSArray*, int32_t) WTF_INTERNAL;
index 3cd52b9..9344f62 100644 (file)
@@ -318,6 +318,17 @@ private:
             break;
         }
 
+        case ArithRound:
+        case ArithFloor:
+        case ArithCeil:
+        case ArithTrunc: {
+            if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass))
+                changed |= setPrediction(SpecInt32Only);
+            else
+                changed |= setPrediction(SpecBytecodeDouble);
+            break;
+        }
+
         case ArithAbs: {
             SpeculatedType childPrediction = node->child1()->prediction();
             if (isInt32OrBooleanSpeculation(childPrediction)
@@ -765,18 +776,6 @@ private:
             break;
         }
 
-        case ArithRound:
-        case ArithFloor:
-        case ArithCeil:
-        case ArithTrunc: {
-            if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
-                && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
-                setPrediction(SpecInt32Only);
-            else
-                setPrediction(SpecBytecodeDouble);
-            break;
-        }
-
         case ArithRandom: {
             setPrediction(SpecDoubleReal);
             break;
@@ -951,6 +950,10 @@ private:
         case ArithMul:
         case ArithDiv:
         case ArithMod:
+        case ArithRound:
+        case ArithFloor:
+        case ArithCeil:
+        case ArithTrunc:
         case ArithAbs:
         case GetByVal:
         case ToThis:
index 16b3677..6f172c7 100644 (file)
@@ -4910,129 +4910,101 @@ void SpeculativeJIT::compileArithMod(Node* node)
 
 void SpeculativeJIT::compileArithRounding(Node* node)
 {
-    if (node->child1().useKind() == DoubleRepUse) {
-        SpeculateDoubleOperand value(this, node->child1());
-        FPRReg valueFPR = value.fpr();
+    ASSERT(node->child1().useKind() == DoubleRepUse);
 
-        auto setResult = [&] (FPRReg resultFPR) {
-            if (producesInteger(node->arithRoundingMode())) {
-                GPRTemporary roundedResultAsInt32(this);
-                FPRTemporary scratch(this);
-                FPRReg scratchFPR = scratch.fpr();
-                GPRReg resultGPR = roundedResultAsInt32.gpr();
-                JITCompiler::JumpList failureCases;
-                m_jit.branchConvertDoubleToInt32(resultFPR, resultGPR, failureCases, scratchFPR, shouldCheckNegativeZero(node->arithRoundingMode()));
-                speculationCheck(Overflow, JSValueRegs(), node, failureCases);
+    SpeculateDoubleOperand value(this, node->child1());
+    FPRReg valueFPR = value.fpr();
 
-                int32Result(resultGPR, node);
-            } else
-                doubleResult(resultFPR, node);
-        };
-
-        if (m_jit.supportsFloatingPointRounding()) {
-            switch (node->op()) {
-            case ArithRound: {
-                FPRTemporary result(this);
-                FPRReg resultFPR = result.fpr();
-                if (producesInteger(node->arithRoundingMode()) && !shouldCheckNegativeZero(node->arithRoundingMode())) {
-                    static const double halfConstant = 0.5;
-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), resultFPR);
-                    m_jit.addDouble(valueFPR, resultFPR);
-                    m_jit.floorDouble(resultFPR, resultFPR);
-                } else {
-                    m_jit.ceilDouble(valueFPR, resultFPR);
-                    FPRTemporary realPart(this);
-                    FPRReg realPartFPR = realPart.fpr();
-                    m_jit.subDouble(resultFPR, valueFPR, realPartFPR);
-
-                    FPRTemporary scratch(this);
-                    FPRReg scratchFPR = scratch.fpr();
-                    static const double halfConstant = 0.5;
-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), scratchFPR);
-
-                    JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
-                    static const double oneConstant = -1.0;
-                    m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), scratchFPR);
-                    m_jit.addDouble(scratchFPR, resultFPR);
-                    shouldUseCeiled.link(&m_jit);
-                }
-                setResult(resultFPR);
-                return;
-            }
+    auto setResult = [&] (FPRReg resultFPR) {
+        if (producesInteger(node->arithRoundingMode())) {
+            GPRTemporary roundedResultAsInt32(this);
+            FPRTemporary scratch(this);
+            FPRReg scratchFPR = scratch.fpr();
+            GPRReg resultGPR = roundedResultAsInt32.gpr();
+            JITCompiler::JumpList failureCases;
+            m_jit.branchConvertDoubleToInt32(resultFPR, resultGPR, failureCases, scratchFPR, shouldCheckNegativeZero(node->arithRoundingMode()));
+            speculationCheck(Overflow, JSValueRegs(), node, failureCases);
 
-            case ArithFloor: {
-                FPRTemporary rounded(this);
-                FPRReg resultFPR = rounded.fpr();
-                m_jit.floorDouble(valueFPR, resultFPR);
-                setResult(resultFPR);
-                return;
-            }
+            int32Result(resultGPR, node);
+        } else
+            doubleResult(resultFPR, node);
+    };
 
-            case ArithCeil: {
-                FPRTemporary rounded(this);
-                FPRReg resultFPR = rounded.fpr();
+    if (m_jit.supportsFloatingPointRounding()) {
+        switch (node->op()) {
+        case ArithRound: {
+            FPRTemporary result(this);
+            FPRReg resultFPR = result.fpr();
+            if (producesInteger(node->arithRoundingMode()) && !shouldCheckNegativeZero(node->arithRoundingMode())) {
+                static const double halfConstant = 0.5;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), resultFPR);
+                m_jit.addDouble(valueFPR, resultFPR);
+                m_jit.floorDouble(resultFPR, resultFPR);
+            } else {
                 m_jit.ceilDouble(valueFPR, resultFPR);
-                setResult(resultFPR);
-                return;
-            }
+                FPRTemporary realPart(this);
+                FPRReg realPartFPR = realPart.fpr();
+                m_jit.subDouble(resultFPR, valueFPR, realPartFPR);
 
-            case ArithTrunc: {
-                FPRTemporary rounded(this);
-                FPRReg resultFPR = rounded.fpr();
-                m_jit.roundTowardZeroDouble(valueFPR, resultFPR);
-                setResult(resultFPR);
-                return;
+                FPRTemporary scratch(this);
+                FPRReg scratchFPR = scratch.fpr();
+                static const double halfConstant = 0.5;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&halfConstant), scratchFPR);
+
+                JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
+                static const double oneConstant = -1.0;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), scratchFPR);
+                m_jit.addDouble(scratchFPR, resultFPR);
+                shouldUseCeiled.link(&m_jit);
             }
+            setResult(resultFPR);
+            return;
+        }
 
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-            }
-        } else {
-            flushRegisters();
-            FPRResult roundedResultAsDouble(this);
-            FPRReg resultFPR = roundedResultAsDouble.fpr();
-            if (node->op() == ArithRound)
-                callOperation(jsRound, resultFPR, valueFPR);
-            else if (node->op() == ArithFloor)
-                callOperation(floor, resultFPR, valueFPR);
-            else if (node->op() == ArithCeil)
-                callOperation(ceil, resultFPR, valueFPR);
-            else {
-                ASSERT(node->op() == ArithTrunc);
-                callOperation(trunc, resultFPR, valueFPR);
-            }
+        case ArithFloor: {
+            FPRTemporary rounded(this);
+            FPRReg resultFPR = rounded.fpr();
+            m_jit.floorDouble(valueFPR, resultFPR);
             setResult(resultFPR);
+            return;
         }
-        return;
-    }
 
-    DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
+        case ArithCeil: {
+            FPRTemporary rounded(this);
+            FPRReg resultFPR = rounded.fpr();
+            m_jit.ceilDouble(valueFPR, resultFPR);
+            setResult(resultFPR);
+            return;
+        }
 
-    JSValueOperand argument(this, node->child1());
-    JSValueRegs argumentRegs = argument.jsValueRegs();
-#if USE(JSVALUE64)
-    GPRTemporary result(this);
-    JSValueRegs resultRegs = JSValueRegs(result.gpr());
-#else
-    GPRTemporary resultTag(this);
-    GPRTemporary resultPayload(this);
-    JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
-#endif
-    flushRegisters();
-    J_JITOperation_EJ operation = nullptr;
-    if (node->op() == ArithRound)
-        operation = operationArithRound;
-    else if (node->op() == ArithFloor)
-        operation = operationArithFloor;
-    else if (node->op() == ArithCeil)
-        operation = operationArithCeil;
-    else {
-        ASSERT(node->op() == ArithTrunc);
-        operation = operationArithTrunc;
+        case ArithTrunc: {
+            FPRTemporary rounded(this);
+            FPRReg resultFPR = rounded.fpr();
+            m_jit.roundTowardZeroDouble(valueFPR, resultFPR);
+            setResult(resultFPR);
+            return;
+        }
+
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    } else {
+        flushRegisters();
+        FPRResult roundedResultAsDouble(this);
+        FPRReg resultFPR = roundedResultAsDouble.fpr();
+        if (node->op() == ArithRound)
+            callOperation(jsRound, resultFPR, valueFPR);
+        else if (node->op() == ArithFloor)
+            callOperation(floor, resultFPR, valueFPR);
+        else if (node->op() == ArithCeil)
+            callOperation(ceil, resultFPR, valueFPR);
+        else {
+            ASSERT(node->op() == ArithTrunc);
+            callOperation(trunc, resultFPR, valueFPR);
+        }
+        m_jit.exceptionCheck();
+        setResult(resultFPR);
     }
-    callOperation(operation, resultRegs, argumentRegs);
-    m_jit.exceptionCheck();
-    jsValueResult(resultRegs, node);
 }
 
 void SpeculativeJIT::compileArithSin(Node* node)
index 08037d8..0b1a02f 100644 (file)
@@ -2266,91 +2266,67 @@ private:
 
     void compileArithRound()
     {
-        if (m_node->child1().useKind() == DoubleRepUse) {
-            LValue result = nullptr;
-            if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
-                LValue value = lowDouble(m_node->child1());
-                result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
-            } else {
-                LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
-                LBasicBlock continuation = m_out.newBlock();
+        LValue result = nullptr;
 
-                LValue value = lowDouble(m_node->child1());
-                LValue integerValue = m_out.doubleCeil(value);
-                ValueFromBlock integerValueResult = m_out.anchor(integerValue);
+        if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
+            LValue value = lowDouble(m_node->child1());
+            result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
+        } else {
+            LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
+            LBasicBlock continuation = m_out.newBlock();
 
-                LValue realPart = m_out.doubleSub(integerValue, value);
+            LValue value = lowDouble(m_node->child1());
+            LValue integerValue = m_out.doubleCeil(value);
+            ValueFromBlock integerValueResult = m_out.anchor(integerValue);
 
-                m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
+            LValue realPart = m_out.doubleSub(integerValue, value);
 
-                LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
-                LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
-                ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
-                m_out.jump(continuation);
-                m_out.appendTo(continuation, lastNext);
+            m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
 
-                result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
-            }
+            LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
+            LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
+            ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
+            m_out.jump(continuation);
+            m_out.appendTo(continuation, lastNext);
 
-            if (producesInteger(m_node->arithRoundingMode())) {
-                LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
-                setInt32(integerValue);
-            } else
-                setDouble(result);
-            return;
+            result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
         }
 
-        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
-        LValue argument = lowJSValue(m_node->child1());
-        setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
+        if (producesInteger(m_node->arithRoundingMode())) {
+            LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
+            setInt32(integerValue);
+        } else
+            setDouble(result);
     }
 
     void compileArithFloor()
     {
-        if (m_node->child1().useKind() == DoubleRepUse) {
-            LValue value = lowDouble(m_node->child1());
-            LValue integerValue = m_out.doubleFloor(value);
-            if (producesInteger(m_node->arithRoundingMode()))
-                setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
-            else
-                setDouble(integerValue);
-            return;
-        }
-        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
-        LValue argument = lowJSValue(m_node->child1());
-        setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
+        LValue value = lowDouble(m_node->child1());
+        LValue integerValue = m_out.doubleFloor(value);
+        if (producesInteger(m_node->arithRoundingMode()))
+            setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+        else
+            setDouble(integerValue);
     }
 
     void compileArithCeil()
     {
-        if (m_node->child1().useKind() == DoubleRepUse) {
-            LValue value = lowDouble(m_node->child1());
-            LValue integerValue = m_out.doubleCeil(value);
-            if (producesInteger(m_node->arithRoundingMode()))
-                setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
-            else
-                setDouble(integerValue);
-            return;
-        }
-        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
-        LValue argument = lowJSValue(m_node->child1());
-        setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
+        LValue value = lowDouble(m_node->child1());
+        LValue integerValue = m_out.doubleCeil(value);
+        if (producesInteger(m_node->arithRoundingMode()))
+            setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+        else
+            setDouble(integerValue);
     }
 
     void compileArithTrunc()
     {
-        if (m_node->child1().useKind() == DoubleRepUse) {
-            LValue value = lowDouble(m_node->child1());
-            LValue result = m_out.doubleTrunc(value);
-            if (producesInteger(m_node->arithRoundingMode()))
-                setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
-            else
-                setDouble(result);
-            return;
-        }
-        DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
-        LValue argument = lowJSValue(m_node->child1());
-        setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
+        LValue value = lowDouble(m_node->child1());
+        LValue result = m_out.doubleTrunc(value);
+        if (producesInteger(m_node->arithRoundingMode()))
+            setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
+        else
+            setDouble(result);
     }
 
     void compileArithSqrt()