<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[197671] releases/WebKitGTK/webkit-2.12</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/197671">197671</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-07 03:08:22 -0800 (Mon, 07 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/197380">r197380</a> - [DFG][FTL][B3] Support floor and ceil
https://bugs.webkit.org/show_bug.cgi?id=154683

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch implements and fixes the following things.

1. Implement Ceil and Floor in DFG, FTL and B3

x86 SSE 4.2 and ARM64 have round instructions that can directly perform Ceil or Floor.
This patch leverages this functionality. We introduce ArithFloor and ArithCeil.
During DFG phase, these nodes attempt to convert itself to Identity (in Fixup phase).
As the same to ArithRound, it tracks arith rounding mode.
And if these nodes are required to emit machine codes, we emit rounding machine code
if it is supported in the current machine. For example, in x86, we emit `round`.

This `Floor` functionality is nice for @toInteger in builtin.
That is used for Array.prototype.{forEach, map, every, some, reduce...}
And according to the benchmark results, Kraken audio-oscillator is slightly improved
due to its frequent Math.round and Math.floor calls.

2. Implement Floor in B3 and Air

As the same to Ceil in B3, we add a new B3 IR and Air opcode, Floor.
This Floor is leveraged to implement ArithFloor in DFG.

3. Fix ArithRound operation

Currently, we used cvtsd2si (in x86) to convert double value to int32.
And we also used this to implement Math.round, like, cvtsd2si(value + 0.5).
However, this implementation is not correct. Because cvtsd2si is not floor operation.
It is trucate operation. This is OK for positive numbers. But NG for negative numbers.
For example, the current implementation accidentally rounds `-0.6` to `-0.0`. This should be `-1.0`.
Using Ceil and Floor instructions, we implement correct ArithRound.

* assembler/MacroAssemblerARM.h:
(JSC::MacroAssemblerARM::supportsFloatingPointRounding):
(JSC::MacroAssemblerARM::ceilDouble):
(JSC::MacroAssemblerARM::floorDouble):
(JSC::MacroAssemblerARM::supportsFloatingPointCeil): Deleted.
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::supportsFloatingPointRounding):
(JSC::MacroAssemblerARM64::floorFloat):
(JSC::MacroAssemblerARM64::supportsFloatingPointCeil): Deleted.
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::supportsFloatingPointRounding):
(JSC::MacroAssemblerARMv7::ceilDouble):
(JSC::MacroAssemblerARMv7::floorDouble):
(JSC::MacroAssemblerARMv7::supportsFloatingPointCeil): Deleted.
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::ceilDouble):
(JSC::MacroAssemblerMIPS::floorDouble):
(JSC::MacroAssemblerMIPS::supportsFloatingPointRounding):
(JSC::MacroAssemblerMIPS::supportsFloatingPointCeil): Deleted.
* assembler/MacroAssemblerSH4.h:
(JSC::MacroAssemblerSH4::supportsFloatingPointRounding):
(JSC::MacroAssemblerSH4::ceilDouble):
(JSC::MacroAssemblerSH4::floorDouble):
(JSC::MacroAssemblerSH4::supportsFloatingPointCeil): Deleted.
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::floorDouble):
(JSC::MacroAssemblerX86Common::floorFloat):
(JSC::MacroAssemblerX86Common::supportsFloatingPointRounding):
(JSC::MacroAssemblerX86Common::supportsFloatingPointCeil): Deleted.
* b3/B3ConstDoubleValue.cpp:
(JSC::B3::ConstDoubleValue::floorConstant):
* b3/B3ConstDoubleValue.h:
* b3/B3ConstFloatValue.cpp:
(JSC::B3::ConstFloatValue::floorConstant):
* b3/B3ConstFloatValue.h:
* b3/B3LowerMacrosAfterOptimizations.cpp:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3ReduceDoubleToFloat.cpp:
* b3/B3ReduceStrength.cpp:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::floorConstant):
(JSC::B3::Value::isRounded):
(JSC::B3::Value::effects):
(JSC::B3::Value::key):
(JSC::B3::Value::typeFor):
* b3/B3Value.h:
* b3/air/AirFixPartialRegisterStalls.cpp:
* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::testFloorCeilArg):
(JSC::B3::testFloorArg):
(JSC::B3::testFloorImm):
(JSC::B3::testFloorMem):
(JSC::B3::testFloorFloorArg):
(JSC::B3::testCeilFloorArg):
(JSC::B3::testFloorIToD64):
(JSC::B3::testFloorIToD32):
(JSC::B3::testFloorArgWithUselessDoubleConversion):
(JSC::B3::testFloorArgWithEffectfulDoubleConversion):
(JSC::B3::run):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGArithMode.cpp:
(WTF::printInternal):
* dfg/DFGArithMode.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::roundShouldSpeculateInt32):
* dfg/DFGNode.h:
(JSC::DFG::Node::arithNodeFlags):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasArithRoundingMode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithRounding):
(JSC::DFG::SpeculativeJIT::compileArithRound): Deleted.
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileArithRound):
(JSC::FTL::DFG::LowerDFGToB3::compileArithFloor):
(JSC::FTL::DFG::LowerDFGToB3::compileArithCeil):
* ftl/FTLOutput.h:
(JSC::FTL::Output::doubleFloor):
* jit/ThunkGenerators.cpp:
(JSC::ceilThunkGenerator):
* tests/stress/math-ceil-arith-rounding-mode.js: Added.
(firstCareAboutZeroSecondDoesNot):
(firstDoNotCareAboutZeroSecondDoes):
(warmup):
(verifyNegativeZeroIsPreserved):
* tests/stress/math-ceil-basics.js: Added.
(mathCeilOnIntegers):
(mathCeilOnDoubles):
(mathCeilOnBooleans):
(uselessMathCeil):
(mathCeilWithOverflow):
(mathCeilConsumedAsDouble):
(mathCeilDoesNotCareAboutMinusZero):
(mathCeilNoArguments):
(mathCeilTooManyArguments):
(testMathCeilOnConstants):
(mathCeilStructTransition):
(Math.ceil):
* tests/stress/math-floor-arith-rounding-mode.js: Added.
(firstCareAboutZeroSecondDoesNot):
(firstDoNotCareAboutZeroSecondDoes):
(warmup):
(verifyNegativeZeroIsPreserved):
* tests/stress/math-floor-basics.js: Added.
(mathFloorOnIntegers):
(mathFloorOnDoubles):
(mathFloorOnBooleans):
(uselessMathFloor):
(mathFloorWithOverflow):
(mathFloorConsumedAsDouble):
(mathFloorDoesNotCareAboutMinusZero):
(mathFloorNoArguments):
(mathFloorTooManyArguments):
(testMathFloorOnConstants):
(mathFloorStructTransition):
(Math.floor):
* tests/stress/math-round-should-not-use-truncate.js: Added.
(mathRoundDoesNotCareAboutMinusZero):
* tests/stress/math-rounding-infinity.js: Added.
(shouldBe):
(testRound):
(testFloor):
(testCeil):
* tests/stress/math-rounding-nan.js: Added.
(shouldBe):
(testRound):
(testFloor):
(testCeil):
* tests/stress/math-rounding-negative-zero.js: Added.
(shouldBe):
(testRound):
(testFloor):
(testCeil):
(testRoundNonNegativeZero):
(testRoundNonNegativeZero2):

Websites/webkit.org:

* docs/b3/intermediate-representation.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARM64h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMv7h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerMIPSh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerSH4h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86Commonh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstDoubleValuecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstDoubleValueh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstFloatValuecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstFloatValueh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerMacrosAfterOptimizationscpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerMacrosAfterOptimizations.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerToAircpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Opcodecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Opcodeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ReduceDoubleToFloatcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ReduceStrengthcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceStrength.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Validatecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Valuecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Valueh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirFixPartialRegisterStallscpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirOpcodeopcodes">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3testb3cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGArithModecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGArithModeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGByteCodeParsercpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGClobberizeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGDoesGCcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGFixupPhasecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGGraphcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGGraphh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGNodeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGNodeTypeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSafeToExecuteh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLCapabilitiescpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLLowerDFGToB3cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCorejitThunkGeneratorscpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212WebsiteswebkitorgChangeLog">releases/WebKitGTK/webkit-2.12/Websites/webkit.org/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212Websiteswebkitorgdocsb3intermediaterepresentationhtml">releases/WebKitGTK/webkit-2.12/Websites/webkit.org/docs/b3/intermediate-representation.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathceilarithroundingmodejs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-arith-rounding-mode.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathceilbasicsjs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-basics.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathfloorarithroundingmodejs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-arith-rounding-mode.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathfloorbasicsjs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-basics.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundshouldnotusetruncatejs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-round-should-not-use-truncate.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundinginfinityjs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-infinity.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundingnanjs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-nan.js</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundingnegativezerojs">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-negative-zero.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1,3 +1,206 @@
</span><ins>+2016-02-29  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [DFG][FTL][B3] Support floor and ceil
+        https://bugs.webkit.org/show_bug.cgi?id=154683
+
+        Reviewed by Filip Pizlo.
+
+        This patch implements and fixes the following things.
+
+        1. Implement Ceil and Floor in DFG, FTL and B3
+
+        x86 SSE 4.2 and ARM64 have round instructions that can directly perform Ceil or Floor.
+        This patch leverages this functionality. We introduce ArithFloor and ArithCeil.
+        During DFG phase, these nodes attempt to convert itself to Identity (in Fixup phase).
+        As the same to ArithRound, it tracks arith rounding mode.
+        And if these nodes are required to emit machine codes, we emit rounding machine code
+        if it is supported in the current machine. For example, in x86, we emit `round`.
+
+        This `Floor` functionality is nice for @toInteger in builtin.
+        That is used for Array.prototype.{forEach, map, every, some, reduce...}
+        And according to the benchmark results, Kraken audio-oscillator is slightly improved
+        due to its frequent Math.round and Math.floor calls.
+
+        2. Implement Floor in B3 and Air
+
+        As the same to Ceil in B3, we add a new B3 IR and Air opcode, Floor.
+        This Floor is leveraged to implement ArithFloor in DFG.
+
+        3. Fix ArithRound operation
+
+        Currently, we used cvtsd2si (in x86) to convert double value to int32.
+        And we also used this to implement Math.round, like, cvtsd2si(value + 0.5).
+        However, this implementation is not correct. Because cvtsd2si is not floor operation.
+        It is trucate operation. This is OK for positive numbers. But NG for negative numbers.
+        For example, the current implementation accidentally rounds `-0.6` to `-0.0`. This should be `-1.0`.
+        Using Ceil and Floor instructions, we implement correct ArithRound.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerARM::ceilDouble):
+        (JSC::MacroAssemblerARM::floorDouble):
+        (JSC::MacroAssemblerARM::supportsFloatingPointCeil): Deleted.
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerARM64::floorFloat):
+        (JSC::MacroAssemblerARM64::supportsFloatingPointCeil): Deleted.
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerARMv7::ceilDouble):
+        (JSC::MacroAssemblerARMv7::floorDouble):
+        (JSC::MacroAssemblerARMv7::supportsFloatingPointCeil): Deleted.
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::ceilDouble):
+        (JSC::MacroAssemblerMIPS::floorDouble):
+        (JSC::MacroAssemblerMIPS::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerMIPS::supportsFloatingPointCeil): Deleted.
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerSH4::ceilDouble):
+        (JSC::MacroAssemblerSH4::floorDouble):
+        (JSC::MacroAssemblerSH4::supportsFloatingPointCeil): Deleted.
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::floorDouble):
+        (JSC::MacroAssemblerX86Common::floorFloat):
+        (JSC::MacroAssemblerX86Common::supportsFloatingPointRounding):
+        (JSC::MacroAssemblerX86Common::supportsFloatingPointCeil): Deleted.
+        * b3/B3ConstDoubleValue.cpp:
+        (JSC::B3::ConstDoubleValue::floorConstant):
+        * b3/B3ConstDoubleValue.h:
+        * b3/B3ConstFloatValue.cpp:
+        (JSC::B3::ConstFloatValue::floorConstant):
+        * b3/B3ConstFloatValue.h:
+        * b3/B3LowerMacrosAfterOptimizations.cpp:
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.cpp:
+        (WTF::printInternal):
+        * b3/B3Opcode.h:
+        * b3/B3ReduceDoubleToFloat.cpp:
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::floorConstant):
+        (JSC::B3::Value::isRounded):
+        (JSC::B3::Value::effects):
+        (JSC::B3::Value::key):
+        (JSC::B3::Value::typeFor):
+        * b3/B3Value.h:
+        * b3/air/AirFixPartialRegisterStalls.cpp:
+        * b3/air/AirOpcode.opcodes:
+        * b3/testb3.cpp:
+        (JSC::B3::testFloorCeilArg):
+        (JSC::B3::testFloorArg):
+        (JSC::B3::testFloorImm):
+        (JSC::B3::testFloorMem):
+        (JSC::B3::testFloorFloorArg):
+        (JSC::B3::testCeilFloorArg):
+        (JSC::B3::testFloorIToD64):
+        (JSC::B3::testFloorIToD32):
+        (JSC::B3::testFloorArgWithUselessDoubleConversion):
+        (JSC::B3::testFloorArgWithEffectfulDoubleConversion):
+        (JSC::B3::run):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGArithMode.cpp:
+        (WTF::printInternal):
+        * dfg/DFGArithMode.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::roundShouldSpeculateInt32):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::arithNodeFlags):
+        (JSC::DFG::Node::hasHeapPrediction):
+        (JSC::DFG::Node::hasArithRoundingMode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithRounding):
+        (JSC::DFG::SpeculativeJIT::compileArithRound): Deleted.
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileArithRound):
+        (JSC::FTL::DFG::LowerDFGToB3::compileArithFloor):
+        (JSC::FTL::DFG::LowerDFGToB3::compileArithCeil):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::doubleFloor):
+        * jit/ThunkGenerators.cpp:
+        (JSC::ceilThunkGenerator):
+        * tests/stress/math-ceil-arith-rounding-mode.js: Added.
+        (firstCareAboutZeroSecondDoesNot):
+        (firstDoNotCareAboutZeroSecondDoes):
+        (warmup):
+        (verifyNegativeZeroIsPreserved):
+        * tests/stress/math-ceil-basics.js: Added.
+        (mathCeilOnIntegers):
+        (mathCeilOnDoubles):
+        (mathCeilOnBooleans):
+        (uselessMathCeil):
+        (mathCeilWithOverflow):
+        (mathCeilConsumedAsDouble):
+        (mathCeilDoesNotCareAboutMinusZero):
+        (mathCeilNoArguments):
+        (mathCeilTooManyArguments):
+        (testMathCeilOnConstants):
+        (mathCeilStructTransition):
+        (Math.ceil):
+        * tests/stress/math-floor-arith-rounding-mode.js: Added.
+        (firstCareAboutZeroSecondDoesNot):
+        (firstDoNotCareAboutZeroSecondDoes):
+        (warmup):
+        (verifyNegativeZeroIsPreserved):
+        * tests/stress/math-floor-basics.js: Added.
+        (mathFloorOnIntegers):
+        (mathFloorOnDoubles):
+        (mathFloorOnBooleans):
+        (uselessMathFloor):
+        (mathFloorWithOverflow):
+        (mathFloorConsumedAsDouble):
+        (mathFloorDoesNotCareAboutMinusZero):
+        (mathFloorNoArguments):
+        (mathFloorTooManyArguments):
+        (testMathFloorOnConstants):
+        (mathFloorStructTransition):
+        (Math.floor):
+        * tests/stress/math-round-should-not-use-truncate.js: Added.
+        (mathRoundDoesNotCareAboutMinusZero):
+        * tests/stress/math-rounding-infinity.js: Added.
+        (shouldBe):
+        (testRound):
+        (testFloor):
+        (testCeil):
+        * tests/stress/math-rounding-nan.js: Added.
+        (shouldBe):
+        (testRound):
+        (testFloor):
+        (testCeil):
+        * tests/stress/math-rounding-negative-zero.js: Added.
+        (shouldBe):
+        (testRound):
+        (testFloor):
+        (testCeil):
+        (testRoundNonNegativeZero):
+        (testRoundNonNegativeZero2):
+
</ins><span class="cx"> 2016-02-29  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add new MethodTable method to get an estimated size for a cell
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1139,7 +1139,7 @@
</span><span class="cx">         return s_isVFPPresent;
</span><span class="cx">     }
</span><span class="cx">     static bool supportsFloatingPointAbs() { return false; }
</span><del>-    static bool supportsFloatingPointCeil() { return false; }
</del><ins>+    static bool supportsFloatingPointRounding() { return false; }
</ins><span class="cx"> 
</span><span class="cx">     void loadFloat(BaseIndex address, FPRegisterID dest)
</span><span class="cx">     {
</span><span class="lines">@@ -1164,10 +1164,16 @@
</span><span class="cx"> 
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID)
</span><span class="cx">     {
</span><del>-        ASSERT(!supportsFloatingPointCeil());
</del><ins>+        ASSERT(!supportsFloatingPointRounding());
</ins><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT(!supportsFloatingPointRounding());
+        CRASH();
+    }
+
</ins><span class="cx">     void storeFloat(FPRegisterID src, BaseIndex address)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.baseIndexTransferFloat(ARMAssembler::StoreFloat, src, address.base, address.index, static_cast&lt;int&gt;(address.scale), address.offset);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1343,7 +1343,7 @@
</span><span class="cx">     static bool supportsFloatingPointTruncate() { return true; }
</span><span class="cx">     static bool supportsFloatingPointSqrt() { return true; }
</span><span class="cx">     static bool supportsFloatingPointAbs() { return true; }
</span><del>-    static bool supportsFloatingPointCeil() { return true; }
</del><ins>+    static bool supportsFloatingPointRounding() { return true; }
</ins><span class="cx"> 
</span><span class="cx">     enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
</span><span class="cx"> 
</span><span class="lines">@@ -1399,6 +1399,11 @@
</span><span class="cx">         m_assembler.frintm&lt;64&gt;(dest, src);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void floorFloat(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.frintm&lt;32&gt;(dest, src);
+    }
+
</ins><span class="cx">     // Convert 'src' to an integer, and places the resulting 'dest'.
</span><span class="cx">     // If the result is not representable as a 32 bit value, branch.
</span><span class="cx">     // May also branch for some values that are representable in 32 bits
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMv7h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -870,7 +870,7 @@
</span><span class="cx">     static bool supportsFloatingPointTruncate() { return true; }
</span><span class="cx">     static bool supportsFloatingPointSqrt() { return true; }
</span><span class="cx">     static bool supportsFloatingPointAbs() { return true; }
</span><del>-    static bool supportsFloatingPointCeil() { return false; }
</del><ins>+    static bool supportsFloatingPointRounding() { return false; }
</ins><span class="cx"> 
</span><span class="cx">     void loadDouble(ImplicitAddress address, FPRegisterID dest)
</span><span class="cx">     {
</span><span class="lines">@@ -1063,10 +1063,16 @@
</span><span class="cx"> 
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID)
</span><span class="cx">     {
</span><del>-        ASSERT(!supportsFloatingPointCeil());
</del><ins>+        ASSERT(!supportsFloatingPointRounding());
</ins><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT(!supportsFloatingPointRounding());
+        CRASH();
+    }
+
</ins><span class="cx">     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.vmov(fpTempRegister, src, src);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerMIPSh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -649,10 +649,16 @@
</span><span class="cx"> 
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID)
</span><span class="cx">     {
</span><del>-        ASSERT(!supportsFloatingPointCeil());
</del><ins>+        ASSERT(!supportsFloatingPointRounding());
</ins><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT(!supportsFloatingPointRounding());
+        CRASH();
+    }
+
</ins><span class="cx">     ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         ConvertibleLoadLabel result(this);
</span><span class="lines">@@ -1237,7 +1243,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx">     static bool supportsFloatingPointAbs() { return false; }
</span><del>-    static bool supportsFloatingPointCeil() { return false; }
</del><ins>+    static bool supportsFloatingPointRounding() { return false; }
</ins><span class="cx"> 
</span><span class="cx">     // Stack manipulation operations:
</span><span class="cx">     //
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerSH4h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1091,7 +1091,7 @@
</span><span class="cx">     static bool supportsFloatingPointTruncate() { return true; }
</span><span class="cx">     static bool supportsFloatingPointSqrt() { return true; }
</span><span class="cx">     static bool supportsFloatingPointAbs() { return true; }
</span><del>-    static bool supportsFloatingPointCeil() { return false; }
</del><ins>+    static bool supportsFloatingPointRounding() { return false; }
</ins><span class="cx"> 
</span><span class="cx">     void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
</span><span class="cx">     {
</span><span class="lines">@@ -1577,10 +1577,16 @@
</span><span class="cx"> 
</span><span class="cx">     NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID)
</span><span class="cx">     {
</span><del>-        ASSERT(!supportsFloatingPointCeil());
</del><ins>+        ASSERT(!supportsFloatingPointRounding());
</ins><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT(!supportsFloatingPointRounding());
+        CRASH();
+    }
+
</ins><span class="cx">     Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
</span><span class="cx">     {
</span><span class="cx">         RegisterID addressTempRegister = claimScratch();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86Commonh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -696,6 +696,26 @@
</span><span class="cx">         m_assembler.roundss_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardInfiniti);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void floorDouble(FPRegisterID src, FPRegisterID dst)
+    {
+        m_assembler.roundsd_rr(src, dst, X86Assembler::RoundingType::TowardNegativeInfiniti);
+    }
+
+    void floorDouble(Address src, FPRegisterID dst)
+    {
+        m_assembler.roundsd_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardNegativeInfiniti);
+    }
+
+    void floorFloat(FPRegisterID src, FPRegisterID dst)
+    {
+        m_assembler.roundss_rr(src, dst, X86Assembler::RoundingType::TowardNegativeInfiniti);
+    }
+
+    void floorFloat(Address src, FPRegisterID dst)
+    {
+        m_assembler.roundss_mr(src.offset, src.base, dst, X86Assembler::RoundingType::TowardNegativeInfiniti);
+    }
+
</ins><span class="cx">     // Memory access operations:
</span><span class="cx">     //
</span><span class="cx">     // Loads are of the form load(address, destination) and stores of the form
</span><span class="lines">@@ -2300,7 +2320,7 @@
</span><span class="cx">         return X86Assembler::maxJumpReplacementSize();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static bool supportsFloatingPointCeil()
</del><ins>+    static bool supportsFloatingPointRounding()
</ins><span class="cx">     {
</span><span class="cx">         if (s_sse4_1CheckState == CPUIDCheckState::NotChecked) {
</span><span class="cx">             int flags = 0;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstDoubleValuecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -97,6 +97,11 @@
</span><span class="cx">     return proc.add&lt;ConstDoubleValue&gt;(origin(), ceil(m_value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ConstDoubleValue::floorConstant(Procedure&amp; proc) const
+{
+    return proc.add&lt;ConstDoubleValue&gt;(origin(), floor(m_value));
+}
+
</ins><span class="cx"> Value* ConstDoubleValue::sqrtConstant(Procedure&amp; proc) const
</span><span class="cx"> {
</span><span class="cx">     return proc.add&lt;ConstDoubleValue&gt;(origin(), sqrt(m_value));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstDoubleValueh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx">     Value* doubleToFloatConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* absConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* ceilConstant(Procedure&amp;) const override;
</span><ins>+    Value* floorConstant(Procedure&amp;) const override;
</ins><span class="cx">     Value* sqrtConstant(Procedure&amp;) const override;
</span><span class="cx"> 
</span><span class="cx">     TriState equalConstant(const Value* other) const override;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstFloatValuecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -97,6 +97,11 @@
</span><span class="cx">     return proc.add&lt;ConstFloatValue&gt;(origin(), ceilf(m_value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ConstFloatValue::floorConstant(Procedure&amp; proc) const
+{
+    return proc.add&lt;ConstFloatValue&gt;(origin(), floorf(m_value));
+}
+
</ins><span class="cx"> Value* ConstFloatValue::sqrtConstant(Procedure&amp; proc) const
</span><span class="cx"> {
</span><span class="cx">     return proc.add&lt;ConstFloatValue&gt;(origin(), static_cast&lt;float&gt;(sqrt(m_value)));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ConstFloatValueh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx">     Value* floatToDoubleConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* absConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* ceilConstant(Procedure&amp;) const override;
</span><ins>+    Value* floorConstant(Procedure&amp;) const override;
</ins><span class="cx">     Value* sqrtConstant(Procedure&amp;) const override;
</span><span class="cx"> 
</span><span class="cx">     TriState equalConstant(const Value* other) const override;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerMacrosAfterOptimizationscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerMacrosAfterOptimizations.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerMacrosAfterOptimizations.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerMacrosAfterOptimizations.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -88,13 +88,12 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case Ceil: {
</span><del>-                if (MacroAssembler::supportsFloatingPointCeil())
</del><ins>+                if (MacroAssembler::supportsFloatingPointRounding())
</ins><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 Value* functionAddress = nullptr;
</span><del>-                double (*ceilDouble)(double) = ceil;
</del><span class="cx">                 if (m_value-&gt;type() == Double)
</span><del>-                    functionAddress = m_insertionSet.insert&lt;ConstPtrValue&gt;(m_index, m_origin, ceilDouble);
</del><ins>+                    functionAddress = m_insertionSet.insert&lt;ConstPtrValue&gt;(m_index, m_origin, ceil);
</ins><span class="cx">                 else if (m_value-&gt;type() == Float)
</span><span class="cx">                     functionAddress = m_insertionSet.insert&lt;ConstPtrValue&gt;(m_index, m_origin, ceilf);
</span><span class="cx">                 else
</span><span class="lines">@@ -109,6 +108,27 @@
</span><span class="cx">                 m_value-&gt;replaceWithIdentity(result);
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            case Floor: {
+                if (MacroAssembler::supportsFloatingPointRounding())
+                    break;
+
+                Value* functionAddress = nullptr;
+                if (m_value-&gt;type() == Double)
+                    functionAddress = m_insertionSet.insert&lt;ConstPtrValue&gt;(m_index, m_origin, floor);
+                else if (m_value-&gt;type() == Float)
+                    functionAddress = m_insertionSet.insert&lt;ConstPtrValue&gt;(m_index, m_origin, floorf);
+                else
+                    RELEASE_ASSERT_NOT_REACHED();
+
+                Value* result = m_insertionSet.insert&lt;CCallValue&gt;(m_index,
+                    m_value-&gt;type(),
+                    m_origin,
+                    Effects::none(),
+                    functionAddress,
+                    m_value-&gt;child(0));
+                m_value-&gt;replaceWithIdentity(result);
+                break;
+            }
</ins><span class="cx">             case Neg: {
</span><span class="cx">                 if (!isFloat(m_value-&gt;type()))
</span><span class="cx">                     break;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1827,6 +1827,11 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case Floor: {
+            appendUnOp&lt;Air::Oops, Air::Oops, FloorDouble, FloorFloat&gt;(m_value-&gt;child(0));
+            return;
+        }
+
</ins><span class="cx">         case Sqrt: {
</span><span class="cx">             appendUnOp&lt;Air::Oops, Air::Oops, SqrtDouble, SqrtFloat&gt;(m_value-&gt;child(0));
</span><span class="cx">             return;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Opcodecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -161,6 +161,9 @@
</span><span class="cx">     case Ceil:
</span><span class="cx">         out.print(&quot;Ceil&quot;);
</span><span class="cx">         return;
</span><ins>+    case Floor:
+        out.print(&quot;Floor&quot;);
+        return;
</ins><span class="cx">     case Sqrt:
</span><span class="cx">         out.print(&quot;Sqrt&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Opcode.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -97,6 +97,7 @@
</span><span class="cx">     // Floating point math.
</span><span class="cx">     Abs,
</span><span class="cx">     Ceil,
</span><ins>+    Floor,
</ins><span class="cx">     Sqrt,
</span><span class="cx"> 
</span><span class="cx">     // Casts and such.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ReduceDoubleToFloatcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceDoubleToFloat.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">         break;
</span><span class="cx">     case Abs:
</span><span class="cx">     case Ceil:
</span><ins>+    case Floor:
</ins><span class="cx">     case Sqrt:
</span><span class="cx">         if (candidate-&gt;child(0)-&gt;opcode() == FloatToDouble) {
</span><span class="cx">             candidate-&gt;child(0) = candidate-&gt;child(0)-&gt;child(0);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -510,8 +510,7 @@
</span><span class="cx">             //    -0 + 0 = 0
</span><span class="cx">             //    -0 + -0 = -0
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0) || m_value-&gt;child(1)-&gt;isNegativeZero()) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -566,8 +565,7 @@
</span><span class="cx">             // Turn this: Neg(Neg(value))
</span><span class="cx">             // Into this: value
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == Neg) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -591,16 +589,14 @@
</span><span class="cx">                 // Note that we don't do this for doubles because that's wrong. For example, -1 * 0
</span><span class="cx">                 // and 1 * 0 yield different results.
</span><span class="cx">                 if (!factor) {
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
-                    m_changed = true;
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 // Turn this: Mul(value, 1)
</span><span class="cx">                 // Into this: value
</span><span class="cx">                 if (factor == 1) {
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                    m_changed = true;
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx"> 
</span><span class="lines">@@ -632,7 +628,7 @@
</span><span class="cx">                 // Turn this: Mul(value, 1)
</span><span class="cx">                 // Into this: value
</span><span class="cx">                 if (factor == 1) {
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="lines">@@ -663,13 +659,13 @@
</span><span class="cx">                     // Into this: 0
</span><span class="cx">                     // We can do this because it's precisely correct for ChillDiv and for Div we
</span><span class="cx">                     // are allowed to do whatever we want.
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 case 1:
</span><span class="cx">                     // Turn this: Div(value, 1)
</span><span class="cx">                     // Into this: value
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 default:
</span><span class="lines">@@ -715,7 +711,7 @@
</span><span class="cx">                             m_insertionSet.insert&lt;Const32Value&gt;(
</span><span class="cx">                                 m_index, m_value-&gt;origin(), magic.shift));
</span><span class="cx">                     }
</span><del>-                    m_value-&gt;replaceWithIdentity(
</del><ins>+                    replaceWithIdentity(
</ins><span class="cx">                         m_insertionSet.insert&lt;Value&gt;(
</span><span class="cx">                             m_index, Add, m_value-&gt;origin(), magicQuotient,
</span><span class="cx">                             m_insertionSet.insert&lt;Value&gt;(
</span><span class="lines">@@ -724,8 +720,6 @@
</span><span class="cx">                                     m_index, m_value-&gt;origin(), 31))));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-
-                m_changed = true;
</del><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -746,7 +740,7 @@
</span><span class="cx">                     // Turn this: Mod(value, 0)
</span><span class="cx">                     // Into this: 0
</span><span class="cx">                     // This is correct according to ChillMod semantics.
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="cx">                 default:
</span><span class="lines">@@ -782,7 +776,7 @@
</span><span class="cx">                         break;
</span><span class="cx">                     }
</span><span class="cx"> 
</span><del>-                    m_value-&gt;replaceWithIdentity(
</del><ins>+                    replaceWithIdentity(
</ins><span class="cx">                         m_insertionSet.insert&lt;Value&gt;(
</span><span class="cx">                             m_index, Sub, m_value-&gt;origin(),
</span><span class="cx">                             m_value-&gt;child(0),
</span><span class="lines">@@ -794,8 +788,6 @@
</span><span class="cx">                                 m_value-&gt;child(1))));
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                
-                m_changed = true;
</del><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -826,16 +818,14 @@
</span><span class="cx">             // Turn this: BitAnd(valueX, valueX)
</span><span class="cx">             // Into this: valueX.
</span><span class="cx">             if (m_value-&gt;child(0) == m_value-&gt;child(1)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Turn this: BitAnd(value, zero-constant)
</span><span class="cx">             // Into this: zero-constant.
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -843,8 +833,7 @@
</span><span class="cx">             // Into this: value.
</span><span class="cx">             if ((m_value-&gt;type() == Int64 &amp;&amp; m_value-&gt;child(1)-&gt;isInt(0xffffffffffffffff))
</span><span class="cx">                 || (m_value-&gt;type() == Int32 &amp;&amp; m_value-&gt;child(1)-&gt;isInt(0xffffffff))) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -854,8 +843,7 @@
</span><span class="cx">                 Value* newValue = m_insertionSet.insert&lt;Value&gt;(
</span><span class="cx">                     m_index, ZExt32, m_value-&gt;origin(),
</span><span class="cx">                     m_insertionSet.insert&lt;Value&gt;(m_index, Trunc, m_value-&gt;origin(), m_value-&gt;child(0)));
</span><del>-                m_value-&gt;replaceWithIdentity(newValue);
-                m_changed = true;
</del><ins>+                replaceWithIdentity(newValue);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -932,16 +920,14 @@
</span><span class="cx">             // Turn this: BitOr(valueX, valueX)
</span><span class="cx">             // Into this: valueX.
</span><span class="cx">             if (m_value-&gt;child(0) == m_value-&gt;child(1)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Turn this: BitOr(value, zero-constant)
</span><span class="cx">             // Into this: value.
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -949,8 +935,7 @@
</span><span class="cx">             // Into this: all-ones.
</span><span class="cx">             if ((m_value-&gt;type() == Int64 &amp;&amp; m_value-&gt;child(1)-&gt;isInt(0xffffffffffffffff))
</span><span class="cx">                 || (m_value-&gt;type() == Int32 &amp;&amp; m_value-&gt;child(1)-&gt;isInt(0xffffffff))) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -997,8 +982,7 @@
</span><span class="cx">             // Turn this: BitXor(value, zero-constant)
</span><span class="cx">             // Into this: value.
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1103,7 +1087,7 @@
</span><span class="cx">             // Turn this: Abs(Abs(value))
</span><span class="cx">             // Into this: Abs(value)
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == Abs) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1120,7 +1104,7 @@
</span><span class="cx">                     m_value-&gt;child(0)-&gt;child(0),
</span><span class="cx">                     mask);
</span><span class="cx">                 Value* cast = m_insertionSet.insert&lt;Value&gt;(m_index, BitwiseCast, m_value-&gt;origin(), bitAnd);
</span><del>-                m_value-&gt;replaceWithIdentity(cast);
</del><ins>+                replaceWithIdentity(cast);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1133,22 +1117,28 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            // Turn this: Ceil(Ceil(value))
-            // Into this: Ceil(value)
-            if (m_value-&gt;child(0)-&gt;opcode() == Ceil) {
-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
</del><ins>+            // Turn this: Ceil(roundedValue)
+            // Into this: roundedValue
+            if (m_value-&gt;child(0)-&gt;isRounded()) {
+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+            break;
</ins><span class="cx"> 
</span><del>-            // Turn this: Ceil(IToD(value))
-            // Into this: IToD(value)
-            //
-            // That works for Int64 because both ARM64 and x86_64
-            // perform rounding when converting a 64bit integer to double.
-            if (m_value-&gt;child(0)-&gt;opcode() == IToD) {
-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
</del><ins>+        case Floor:
+            // Turn this: Floor(constant)
+            // Into this: floor&lt;value-&gt;type()&gt;(constant)
+            if (Value* constant = m_value-&gt;child(0)-&gt;floorConstant(m_proc)) {
+                replaceWithNewValue(constant);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><ins>+
+            // Turn this: Floor(roundedValue)
+            // Into this: roundedValue
+            if (m_value-&gt;child(0)-&gt;isRounded()) {
+                replaceWithIdentity(m_value-&gt;child(0));
+                break;
+            }
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Sqrt:
</span><span class="lines">@@ -1171,8 +1161,7 @@
</span><span class="cx">             // Turn this: BitwiseCast(BitwiseCast(value))
</span><span class="cx">             // Into this: value
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == BitwiseCast) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1238,8 +1227,7 @@
</span><span class="cx">             // Turn this: SExt16(SExt8(value))
</span><span class="cx">             // Into this: SExt8(value)
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == SExt8) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1311,8 +1299,7 @@
</span><span class="cx">             // Turn this: Trunc(SExt32(value)) or Trunc(ZExt32(value))
</span><span class="cx">             // Into this: value
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == SExt32 || m_value-&gt;child(0)-&gt;opcode() == ZExt32) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1350,8 +1337,7 @@
</span><span class="cx">             // Turn this: DoubleToFloat(FloatToDouble(value))
</span><span class="cx">             // Into this: value
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;opcode() == FloatToDouble) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0)-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1367,9 +1353,8 @@
</span><span class="cx">             // Turn this: Select(constant, a, b)
</span><span class="cx">             // Into this: constant ? a : b
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;hasInt32()) {
</span><del>-                m_value-&gt;replaceWithIdentity(
</del><ins>+                replaceWithIdentity(
</ins><span class="cx">                     m_value-&gt;child(0)-&gt;asInt32() ? m_value-&gt;child(1) : m_value-&gt;child(2));
</span><del>-                m_changed = true;
</del><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1407,8 +1392,7 @@
</span><span class="cx">             // Turn this: Select(stuff, x, x)
</span><span class="cx">             // Into this: x
</span><span class="cx">             if (m_value-&gt;child(1) == m_value-&gt;child(2)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(1));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(1));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1491,8 +1475,7 @@
</span><span class="cx">             // Turn this Equal(bool, 1)
</span><span class="cx">             // Into this: bool
</span><span class="cx">             if (m_value-&gt;child(0)-&gt;returnsBool() &amp;&amp; m_value-&gt;child(1)-&gt;isInt32(1)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1511,8 +1494,7 @@
</span><span class="cx">                 // Turn this: NotEqual(bool, 0)
</span><span class="cx">                 // Into this: bool
</span><span class="cx">                 if (m_value-&gt;child(1)-&gt;isInt32(0)) {
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                    m_changed = true;
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="lines">@@ -1613,8 +1595,7 @@
</span><span class="cx">             handleCommutativity();
</span><span class="cx">             
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1633,8 +1614,7 @@
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             if (m_value-&gt;child(1)-&gt;isInt(0)) {
</span><del>-                m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                m_changed = true;
</del><ins>+                replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -1669,8 +1649,7 @@
</span><span class="cx">                     replaceWithNewValue(m_proc.addIntConstant(m_value, 0));
</span><span class="cx">                     break;
</span><span class="cx">                 case 1:
</span><del>-                    m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-                    m_changed = true;
</del><ins>+                    replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">                     break;
</span><span class="cx">                 case 2:
</span><span class="cx">                     m_value-&gt;as&lt;CheckValue&gt;()-&gt;convertToAdd();
</span><span class="lines">@@ -2110,12 +2089,17 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void replaceWithIdentity(Value* newValue)
+    {
+        m_value-&gt;replaceWithIdentity(newValue);
+        m_changed = true;
+    }
+
</ins><span class="cx">     bool handleShiftAmount()
</span><span class="cx">     {
</span><span class="cx">         // Shift anything by zero is identity.
</span><span class="cx">         if (m_value-&gt;child(1)-&gt;isInt32(0)) {
</span><del>-            m_value-&gt;replaceWithIdentity(m_value-&gt;child(0));
-            m_changed = true;
</del><ins>+            replaceWithIdentity(m_value-&gt;child(0));
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Validate.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Validate.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Validate.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -241,6 +241,7 @@
</span><span class="cx">                 break;
</span><span class="cx">             case Abs:
</span><span class="cx">             case Ceil:
</span><ins>+            case Floor:
</ins><span class="cx">             case Sqrt:
</span><span class="cx">                 VALIDATE(value-&gt;numChildren() == 1, (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(isFloat(value-&gt;child(0)-&gt;type()), (&quot;At &quot;, *value));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -287,6 +287,11 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Value::floorConstant(Procedure&amp;) const
+{
+    return nullptr;
+}
+
</ins><span class="cx"> Value* Value::sqrtConstant(Procedure&amp;) const
</span><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="lines">@@ -356,6 +361,30 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Value::isRounded() const
+{
+    ASSERT(isFloat(type()));
+    switch (opcode()) {
+    case Floor:
+    case Ceil:
+    case IToD:
+        return true;
+
+    case ConstDouble: {
+        double value = asDouble();
+        return std::isfinite(value) &amp;&amp; value == ceil(value);
+    }
+
+    case ConstFloat: {
+        float value = asFloat();
+        return std::isfinite(value) &amp;&amp; value == ceilf(value);
+    }
+
+    default:
+        return false;
+    }
+}
+
</ins><span class="cx"> bool Value::returnsBool() const
</span><span class="cx"> {
</span><span class="cx">     if (type() != Int32)
</span><span class="lines">@@ -432,6 +461,7 @@
</span><span class="cx">     case Clz:
</span><span class="cx">     case Abs:
</span><span class="cx">     case Ceil:
</span><ins>+    case Floor:
</ins><span class="cx">     case Sqrt:
</span><span class="cx">     case BitwiseCast:
</span><span class="cx">     case SExt8:
</span><span class="lines">@@ -514,6 +544,7 @@
</span><span class="cx">     case Identity:
</span><span class="cx">     case Abs:
</span><span class="cx">     case Ceil:
</span><ins>+    case Floor:
</ins><span class="cx">     case Sqrt:
</span><span class="cx">     case SExt8:
</span><span class="cx">     case SExt16:
</span><span class="lines">@@ -629,6 +660,7 @@
</span><span class="cx">     case Clz:
</span><span class="cx">     case Abs:
</span><span class="cx">     case Ceil:
</span><ins>+    case Floor:
</ins><span class="cx">     case Sqrt:
</span><span class="cx">     case CheckAdd:
</span><span class="cx">     case CheckSub:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3Value.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -137,6 +137,7 @@
</span><span class="cx">     virtual Value* floatToDoubleConstant(Procedure&amp;) const;
</span><span class="cx">     virtual Value* absConstant(Procedure&amp;) const;
</span><span class="cx">     virtual Value* ceilConstant(Procedure&amp;) const;
</span><ins>+    virtual Value* floorConstant(Procedure&amp;) const;
</ins><span class="cx">     virtual Value* sqrtConstant(Procedure&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     virtual TriState equalConstant(const Value* other) const;
</span><span class="lines">@@ -190,6 +191,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool isNegativeZero() const;
</span><span class="cx"> 
</span><ins>+    bool isRounded() const;
+
</ins><span class="cx">     TriState asTriState() const;
</span><span class="cx">     bool isLikeZero() const { return asTriState() == FalseTriState; }
</span><span class="cx">     bool isLikeNonZero() const { return asTriState() == TrueTriState; }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirFixPartialRegisterStallscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -54,6 +54,8 @@
</span><span class="cx">     case SqrtFloat:
</span><span class="cx">     case CeilDouble:
</span><span class="cx">     case CeilFloat:
</span><ins>+    case FloorDouble:
+    case FloorFloat:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         break;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -432,6 +432,14 @@
</span><span class="cx">     Tmp, Tmp
</span><span class="cx">     x86: Addr, Tmp
</span><span class="cx"> 
</span><ins>+FloorDouble U:F:64, D:F:64
+    Tmp, Tmp
+    x86: Addr, Tmp
+
+FloorFloat U:F:32, D:F:32
+    Tmp, Tmp
+    x86: Addr, Tmp
+
</ins><span class="cx"> SqrtDouble U:F:64, D:F:64
</span><span class="cx">     Tmp, Tmp
</span><span class="cx">     x86: Addr, Tmp
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -3377,6 +3377,18 @@
</span><span class="cx">     CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), ceil(a)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testFloorCeilArg(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* firstCeil = root-&gt;appendNew&lt;Value&gt;(proc, Ceil, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), FPRInfo::argumentFPR0));
+    Value* wrappingFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), firstCeil);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), wrappingFloor);
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), ceil(a)));
+}
+
</ins><span class="cx"> void testCeilIToD64(int64_t a)
</span><span class="cx"> {
</span><span class="cx">     Procedure proc;
</span><span class="lines">@@ -3459,6 +3471,20 @@
</span><span class="cx">     CHECK(isIdentical(compileAndRun&lt;float&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), ceilf(a)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testFloorCeilArg(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* argument = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* firstCeil = root-&gt;appendNew&lt;Value&gt;(proc, Ceil, Origin(), argument);
+    Value* wrappingFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), firstCeil);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), wrappingFloor);
+
+    CHECK(isIdentical(compileAndRun&lt;float&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), ceilf(a)));
+}
+
</ins><span class="cx"> void testCeilArgWithUselessDoubleConversion(float a)
</span><span class="cx"> {
</span><span class="cx">     Procedure proc;
</span><span class="lines">@@ -3496,6 +3522,201 @@
</span><span class="cx">     CHECK(isIdentical(effect, ceilf(a)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testFloorArg(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(
+            proc, Floor, Origin(),
+                root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), FPRInfo::argumentFPR0)));
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), floor(a)));
+}
+
+void testFloorImm(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument = root-&gt;appendNew&lt;ConstDoubleValue&gt;(proc, Origin(), a);
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argument));
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc), floor(a)));
+}
+
+void testFloorMem(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* address = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
+    MemoryValue* loadDouble = root-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, Double, Origin(), address);
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), loadDouble));
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, &amp;a), floor(a)));
+}
+
+void testFloorFloorArg(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* firstFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), FPRInfo::argumentFPR0));
+    Value* secondFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), firstFloor);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), secondFloor);
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), floor(a)));
+}
+
+void testCeilFloorArg(double a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* firstFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), FPRInfo::argumentFPR0));
+    Value* wrappingCeil = root-&gt;appendNew&lt;Value&gt;(proc, Ceil, Origin(), firstFloor);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), wrappingCeil);
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), floor(a)));
+}
+
+void testFloorIToD64(int64_t a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
+    Value* argumentAsDouble = root-&gt;appendNew&lt;Value&gt;(proc, IToD, Origin(), argument);
+
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argumentAsDouble));
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), floor(static_cast&lt;double&gt;(a))));
+}
+
+void testFloorIToD32(int64_t a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* argumentAsDouble = root-&gt;appendNew&lt;Value&gt;(proc, IToD, Origin(), argument);
+
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argumentAsDouble));
+
+    CHECK(isIdentical(compileAndRun&lt;double&gt;(proc, a), floor(static_cast&lt;double&gt;(a))));
+}
+
+void testFloorArg(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* argument = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argument);
+    Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), result);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
+
+    CHECK(isIdentical(compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), bitwise_cast&lt;int32_t&gt;(floorf(a))));
+}
+
+void testFloorImm(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument = root-&gt;appendNew&lt;ConstFloatValue&gt;(proc, Origin(), a);
+    Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argument);
+    Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), result);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
+
+    CHECK(isIdentical(compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), bitwise_cast&lt;int32_t&gt;(floorf(a))));
+}
+
+void testFloorMem(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* address = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0);
+    MemoryValue* loadFloat = root-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, Float, Origin(), address);
+    Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), loadFloat);
+    Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), result);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
+
+    CHECK(isIdentical(compileAndRun&lt;int32_t&gt;(proc, &amp;a), bitwise_cast&lt;int32_t&gt;(floorf(a))));
+}
+
+void testFloorFloorArg(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* argument = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* firstFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argument);
+    Value* secondFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), firstFloor);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), secondFloor);
+
+    CHECK(isIdentical(compileAndRun&lt;float&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), floorf(a)));
+}
+
+void testCeilFloorArg(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* argument = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* firstFloor = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), argument);
+    Value* wrappingCeil = root-&gt;appendNew&lt;Value&gt;(proc, Ceil, Origin(), firstFloor);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), wrappingCeil);
+
+    CHECK(isIdentical(compileAndRun&lt;float&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), floorf(a)));
+}
+
+void testFloorArgWithUselessDoubleConversion(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* floatValue = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* asDouble = root-&gt;appendNew&lt;Value&gt;(proc, FloatToDouble, Origin(), floatValue);
+    Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), asDouble);
+    Value* floatResult = root-&gt;appendNew&lt;Value&gt;(proc, DoubleToFloat, Origin(), result);
+    Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), floatResult);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
+
+    CHECK(isIdentical(compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a)), bitwise_cast&lt;int32_t&gt;(floorf(a))));
+}
+
+void testFloorArgWithEffectfulDoubleConversion(float a)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument32 = root-&gt;appendNew&lt;Value&gt;(proc, Trunc, Origin(),
+        root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0));
+    Value* floatValue = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), argument32);
+    Value* asDouble = root-&gt;appendNew&lt;Value&gt;(proc, FloatToDouble, Origin(), floatValue);
+    Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Floor, Origin(), asDouble);
+    Value* floatResult = root-&gt;appendNew&lt;Value&gt;(proc, DoubleToFloat, Origin(), result);
+    Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), floatResult);
+    Value* doubleAddress = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR1);
+    root-&gt;appendNew&lt;MemoryValue&gt;(proc, Store, Origin(), result, doubleAddress);
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
+
+    double effect = 0;
+    int32_t resultValue = compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a), &amp;effect);
+    CHECK(isIdentical(resultValue, bitwise_cast&lt;int32_t&gt;(floorf(a))));
+    CHECK(isIdentical(effect, floorf(a)));
+}
+
</ins><span class="cx"> void testSqrtArg(double a)
</span><span class="cx"> {
</span><span class="cx">     Procedure proc;
</span><span class="lines">@@ -11142,15 +11363,32 @@
</span><span class="cx">     RUN_UNARY(testCeilImm, floatingPointOperands&lt;double&gt;());
</span><span class="cx">     RUN_UNARY(testCeilMem, floatingPointOperands&lt;double&gt;());
</span><span class="cx">     RUN_UNARY(testCeilCeilArg, floatingPointOperands&lt;double&gt;());
</span><ins>+    RUN_UNARY(testFloorCeilArg, floatingPointOperands&lt;double&gt;());
</ins><span class="cx">     RUN_UNARY(testCeilIToD64, int64Operands());
</span><span class="cx">     RUN_UNARY(testCeilIToD32, int32Operands());
</span><span class="cx">     RUN_UNARY(testCeilArg, floatingPointOperands&lt;float&gt;());
</span><span class="cx">     RUN_UNARY(testCeilImm, floatingPointOperands&lt;float&gt;());
</span><span class="cx">     RUN_UNARY(testCeilMem, floatingPointOperands&lt;float&gt;());
</span><span class="cx">     RUN_UNARY(testCeilCeilArg, floatingPointOperands&lt;float&gt;());
</span><ins>+    RUN_UNARY(testFloorCeilArg, floatingPointOperands&lt;float&gt;());
</ins><span class="cx">     RUN_UNARY(testCeilArgWithUselessDoubleConversion, floatingPointOperands&lt;float&gt;());
</span><span class="cx">     RUN_UNARY(testCeilArgWithEffectfulDoubleConversion, floatingPointOperands&lt;float&gt;());
</span><span class="cx"> 
</span><ins>+    RUN_UNARY(testFloorArg, floatingPointOperands&lt;double&gt;());
+    RUN_UNARY(testFloorImm, floatingPointOperands&lt;double&gt;());
+    RUN_UNARY(testFloorMem, floatingPointOperands&lt;double&gt;());
+    RUN_UNARY(testFloorFloorArg, floatingPointOperands&lt;double&gt;());
+    RUN_UNARY(testCeilFloorArg, floatingPointOperands&lt;double&gt;());
+    RUN_UNARY(testFloorIToD64, int64Operands());
+    RUN_UNARY(testFloorIToD32, int32Operands());
+    RUN_UNARY(testFloorArg, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testFloorImm, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testFloorMem, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testFloorFloorArg, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testCeilFloorArg, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testFloorArgWithUselessDoubleConversion, floatingPointOperands&lt;float&gt;());
+    RUN_UNARY(testFloorArgWithEffectfulDoubleConversion, floatingPointOperands&lt;float&gt;());
+
</ins><span class="cx">     RUN_UNARY(testSqrtArg, floatingPointOperands&lt;double&gt;());
</span><span class="cx">     RUN_UNARY(testSqrtImm, floatingPointOperands&lt;double&gt;());
</span><span class="cx">     RUN_UNARY(testSqrtMem, floatingPointOperands&lt;double&gt;());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -833,10 +833,20 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case ArithRound: {
</del><ins>+    case ArithRound:
+    case ArithFloor:
+    case ArithCeil: {
</ins><span class="cx">         JSValue operand = forNode(node-&gt;child1()).value();
</span><span class="cx">         if (operand &amp;&amp; operand.isNumber()) {
</span><del>-            double roundedValue = jsRound(operand.asNumber());
</del><ins>+            double roundedValue = 0;
+            if (node-&gt;op() == ArithRound)
+                roundedValue = jsRound(operand.asNumber());
+            else if (node-&gt;op() == ArithFloor)
+                roundedValue = floor(operand.asNumber());
+            else {
+                ASSERT(node-&gt;op() == ArithCeil);
+                roundedValue = ceil(operand.asNumber());
+            }
</ins><span class="cx"> 
</span><span class="cx">             if (producesInteger(node-&gt;arithRoundingMode())) {
</span><span class="cx">                 int32_t roundedValueAsInt32 = static_cast&lt;int32_t&gt;(roundedValue);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGArithModecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -55,6 +55,22 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void printInternal(PrintStream&amp; out, JSC::DFG::Arith::RoundingMode mode)
+{
+    switch (mode) {
+    case JSC::DFG::Arith::RoundingMode::Int32:
+        out.print(&quot;Int32&quot;);
+        return;
+    case JSC::DFG::Arith::RoundingMode::Int32WithNegativeZeroCheck:
+        out.print(&quot;Int32WithNegativeZeroCheck&quot;);
+        return;
+    case JSC::DFG::Arith::RoundingMode::Double:
+        out.print(&quot;Double&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGArithModeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGArithMode.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -146,6 +146,7 @@
</span><span class="cx"> 
</span><span class="cx"> class PrintStream;
</span><span class="cx"> void printInternal(PrintStream&amp;, JSC::DFG::Arith::Mode);
</span><ins>+void printInternal(PrintStream&amp;, JSC::DFG::Arith::RoundingMode);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -2188,7 +2188,9 @@
</span><span class="cx">         
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    case RoundIntrinsic: {
</del><ins>+    case RoundIntrinsic:
+    case FloorIntrinsic:
+    case CeilIntrinsic: {
</ins><span class="cx">         if (argumentCountIncludingThis == 1) {
</span><span class="cx">             insertChecks();
</span><span class="cx">             set(VirtualRegister(resultOperand), addToGraph(JSConstant, OpInfo(m_constantNaN)));
</span><span class="lines">@@ -2197,7 +2199,16 @@
</span><span class="cx">         if (argumentCountIncludingThis == 2) {
</span><span class="cx">             insertChecks();
</span><span class="cx">             Node* operand = get(virtualRegisterForArgument(1, registerOffset));
</span><del>-            Node* roundNode = addToGraph(ArithRound, OpInfo(0), OpInfo(prediction), operand);
</del><ins>+            NodeType op;
+            if (intrinsic == RoundIntrinsic)
+                op = ArithRound;
+            else if (intrinsic == FloorIntrinsic)
+                op = ArithFloor;
+            else {
+                ASSERT(intrinsic == CeilIntrinsic);
+                op = ArithCeil;
+            }
+            Node* roundNode = addToGraph(op, OpInfo(0), OpInfo(prediction), operand);
</ins><span class="cx">             set(VirtualRegister(resultOperand), roundNode);
</span><span class="cx">             return true;
</span><span class="cx">         }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGClobberize.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -297,6 +297,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">     case ArithRound:
</span><ins>+    case ArithFloor:
+    case ArithCeil:
</ins><span class="cx">         def(PureValue(node, static_cast&lt;uintptr_t&gt;(node-&gt;arithRoundingMode())));
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -87,6 +87,8 @@
</span><span class="cx">     case ArithSqrt:
</span><span class="cx">     case ArithRandom:
</span><span class="cx">     case ArithRound:
</span><ins>+    case ArithFloor:
+    case ArithCeil:
</ins><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithSin:
</span><span class="cx">     case ArithCos:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -363,7 +363,9 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case ArithRound: {
</del><ins>+        case ArithRound:
+        case ArithFloor:
+        case ArithCeil: {
</ins><span class="cx">             if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
</span><span class="cx">                 fixIntOrBooleanEdge(node-&gt;child1());
</span><span class="cx">                 insertCheck&lt;Int32Use&gt;(m_indexInBlock, node-&gt;child1().node());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -222,6 +222,8 @@
</span><span class="cx">         out.print(comma, node-&gt;arrayMode());
</span><span class="cx">     if (node-&gt;hasArithMode())
</span><span class="cx">         out.print(comma, node-&gt;arithMode());
</span><ins>+    if (node-&gt;hasArithRoundingMode())
+        out.print(comma, &quot;Rounding:&quot;, node-&gt;arithRoundingMode());
</ins><span class="cx">     if (node-&gt;hasScopeOffset())
</span><span class="cx">         out.print(comma, node-&gt;scopeOffset());
</span><span class="cx">     if (node-&gt;hasDirectArgumentsOffset())
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGGraph.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -316,7 +316,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool roundShouldSpeculateInt32(Node* arithRound, PredictionPass pass)
</span><span class="cx">     {
</span><del>-        ASSERT(arithRound-&gt;op() == ArithRound);
</del><ins>+        ASSERT(arithRound-&gt;op() == ArithRound || arithRound-&gt;op() == ArithFloor || arithRound-&gt;op() == ArithCeil);
</ins><span class="cx">         return arithRound-&gt;canSpeculateInt32(pass) &amp;&amp; !hasExitSite(arithRound-&gt;origin.semantic, Overflow) &amp;&amp; !hasExitSite(arithRound-&gt;origin.semantic, NegativeZero);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNode.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNode.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNode.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -928,7 +928,7 @@
</span><span class="cx">     NodeFlags arithNodeFlags()
</span><span class="cx">     {
</span><span class="cx">         NodeFlags result = m_flags &amp; NodeArithFlagsMask;
</span><del>-        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
</del><ins>+        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == DoubleAsInt32)
</ins><span class="cx">             return result;
</span><span class="cx">         return result &amp; ~NodeBytecodeNeedsNegZero;
</span><span class="cx">     }
</span><span class="lines">@@ -1334,6 +1334,8 @@
</span><span class="cx">     {
</span><span class="cx">         switch (op()) {
</span><span class="cx">         case ArithRound:
</span><ins>+        case ArithFloor:
+        case ArithCeil:
</ins><span class="cx">         case GetDirectPname:
</span><span class="cx">         case GetById:
</span><span class="cx">         case GetByIdFlush:
</span><span class="lines">@@ -1715,7 +1717,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool hasArithRoundingMode()
</span><span class="cx">     {
</span><del>-        return op() == ArithRound;
</del><ins>+        return op() == ArithRound || op() == ArithFloor || op() == ArithCeil;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Arith::RoundingMode arithRoundingMode()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNodeType.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -154,6 +154,8 @@
</span><span class="cx">     macro(ArithPow, NodeResultNumber) \
</span><span class="cx">     macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
</span><span class="cx">     macro(ArithRound, NodeResultNumber) \
</span><ins>+    macro(ArithFloor, NodeResultNumber) \
+    macro(ArithCeil, NodeResultNumber) \
</ins><span class="cx">     macro(ArithSqrt, NodeResultNumber) \
</span><span class="cx">     macro(ArithSin, NodeResultNumber) \
</span><span class="cx">     macro(ArithCos, NodeResultNumber) \
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -386,7 +386,9 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case ArithRound: {
</del><ins>+        case ArithRound:
+        case ArithFloor:
+        case ArithCeil: {
</ins><span class="cx">             if (isInt32OrBooleanSpeculation(node-&gt;getHeapPrediction()) &amp;&amp; m_graph.roundShouldSpeculateInt32(node, m_pass))
</span><span class="cx">                 changed |= setPrediction(SpecInt32);
</span><span class="cx">             else
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -181,6 +181,8 @@
</span><span class="cx">     case ArithSqrt:
</span><span class="cx">     case ArithFRound:
</span><span class="cx">     case ArithRound:
</span><ins>+    case ArithFloor:
+    case ArithCeil:
</ins><span class="cx">     case ArithSin:
</span><span class="cx">     case ArithCos:
</span><span class="cx">     case ArithLog:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -4412,46 +4412,93 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeJIT::compileArithRound(Node* node)
</del><ins>+void SpeculativeJIT::compileArithRounding(Node* node)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(node-&gt;child1().useKind() == DoubleRepUse);
</span><span class="cx"> 
</span><span class="cx">     SpeculateDoubleOperand value(this, node-&gt;child1());
</span><span class="cx">     FPRReg valueFPR = value.fpr();
</span><span class="cx"> 
</span><del>-    if (producesInteger(node-&gt;arithRoundingMode()) &amp;&amp; !shouldCheckNegativeZero(node-&gt;arithRoundingMode())) {
-        FPRTemporary oneHalf(this);
-        GPRTemporary roundedResultAsInt32(this);
-        FPRReg oneHalfFPR = oneHalf.fpr();
-        GPRReg resultGPR = roundedResultAsInt32.gpr();
</del><ins>+    auto setResult = [&amp;] (FPRReg resultFPR) {
+        if (producesInteger(node-&gt;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-&gt;arithRoundingMode()));
+            speculationCheck(Overflow, JSValueRegs(), node, failureCases);
</ins><span class="cx"> 
</span><del>-        static const double halfConstant = 0.5;
-        m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;halfConstant), oneHalfFPR);
-        m_jit.addDouble(valueFPR, oneHalfFPR);
</del><ins>+            int32Result(resultGPR, node);
+        } else
+            doubleResult(resultFPR, node);
+    };
</ins><span class="cx"> 
</span><del>-        JITCompiler::Jump truncationFailed = m_jit.branchTruncateDoubleToInt32(oneHalfFPR, resultGPR);
-        speculationCheck(Overflow, JSValueRegs(), node, truncationFailed);
-        int32Result(resultGPR, node);
-        return;
-    }
</del><ins>+    if (m_jit.supportsFloatingPointRounding()) {
+        switch (node-&gt;op()) {
+        case ArithRound: {
+            FPRTemporary result(this);
+            FPRReg resultFPR = result.fpr();
+            if (producesInteger(node-&gt;arithRoundingMode()) &amp;&amp; !shouldCheckNegativeZero(node-&gt;arithRoundingMode())) {
+                static const double halfConstant = 0.5;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;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);
</ins><span class="cx"> 
</span><del>-    flushRegisters();
-    FPRResult roundedResultAsDouble(this);
-    FPRReg resultFPR = roundedResultAsDouble.fpr();
-    callOperation(jsRound, resultFPR, valueFPR);
-    m_jit.exceptionCheck();
-    if (producesInteger(node-&gt;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);
-        speculationCheck(Overflow, JSValueRegs(), node, failureCases);
</del><ins>+                FPRTemporary scratch(this);
+                FPRReg scratchFPR = scratch.fpr();
+                static const double halfConstant = 0.5;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;halfConstant), scratchFPR);
</ins><span class="cx"> 
</span><del>-        int32Result(resultGPR, node);
-    } else
-        doubleResult(resultFPR, node);
</del><ins>+                JITCompiler::Jump shouldUseCeiled = m_jit.branchDouble(JITCompiler::DoubleLessThanOrEqual, realPartFPR, scratchFPR);
+                static const double oneConstant = -1.0;
+                m_jit.loadDouble(MacroAssembler::TrustedImmPtr(&amp;oneConstant), scratchFPR);
+                m_jit.addDouble(scratchFPR, resultFPR);
+                shouldUseCeiled.link(&amp;m_jit);
+            }
+            setResult(resultFPR);
+            return;
+        }
+
+        case ArithFloor: {
+            FPRTemporary rounded(this);
+            FPRReg resultFPR = rounded.fpr();
+            m_jit.floorDouble(valueFPR, resultFPR);
+            setResult(resultFPR);
+            return;
+        }
+
+        case ArithCeil: {
+            FPRTemporary rounded(this);
+            FPRReg resultFPR = rounded.fpr();
+            m_jit.ceilDouble(valueFPR, resultFPR);
+            setResult(resultFPR);
+            return;
+        }
+
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    } else {
+        flushRegisters();
+        FPRResult roundedResultAsDouble(this);
+        FPRReg resultFPR = roundedResultAsDouble.fpr();
+        if (node-&gt;op() == ArithRound)
+            callOperation(jsRound, resultFPR, valueFPR);
+        else if (node-&gt;op() == ArithFloor)
+            callOperation(floor, resultFPR, valueFPR);
+        else {
+            ASSERT(node-&gt;op() == ArithCeil);
+            callOperation(ceil, resultFPR, valueFPR);
+        }
+        m_jit.exceptionCheck();
+        setResult(resultFPR);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeJIT::compileArithSqrt(Node* node)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -2267,7 +2267,9 @@
</span><span class="cx">     void compileArithDiv(Node*);
</span><span class="cx">     void compileArithMod(Node*);
</span><span class="cx">     void compileArithPow(Node*);
</span><del>-    void compileArithRound(Node*);
</del><ins>+    void compileArithRounding(Node*);
+    void compileArithFloor(Node*);
+    void compileArithCeil(Node*);
</ins><span class="cx">     void compileArithRandom(Node*);
</span><span class="cx">     void compileArithSqrt(Node*);
</span><span class="cx">     void compileArithLog(Node*);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -2292,7 +2292,9 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case ArithRound:
</span><del>-        compileArithRound(node);
</del><ins>+    case ArithFloor:
+    case ArithCeil:
+        compileArithRounding(node);
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case ArithSin: {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -2415,7 +2415,9 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case ArithRound:
</span><del>-        compileArithRound(node);
</del><ins>+    case ArithFloor:
+    case ArithCeil:
+        compileArithRounding(node);
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case ArithSin: {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -97,6 +97,8 @@
</span><span class="cx">     case ArithPow:
</span><span class="cx">     case ArithRandom:
</span><span class="cx">     case ArithRound:
</span><ins>+    case ArithFloor:
+    case ArithCeil:
</ins><span class="cx">     case ArithSqrt:
</span><span class="cx">     case ArithLog:
</span><span class="cx">     case ArithFRound:
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -523,6 +523,12 @@
</span><span class="cx">         case ArithRound:
</span><span class="cx">             compileArithRound();
</span><span class="cx">             break;
</span><ins>+        case ArithFloor:
+            compileArithFloor();
+            break;
+        case ArithCeil:
+            compileArithCeil();
+            break;
</ins><span class="cx">         case ArithSqrt:
</span><span class="cx">             compileArithSqrt();
</span><span class="cx">             break;
</span><span class="lines">@@ -1890,25 +1896,32 @@
</span><span class="cx"> 
</span><span class="cx">     void compileArithRound()
</span><span class="cx">     {
</span><del>-        LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, (&quot;ArithRound should round down&quot;));
-        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;ArithRound continuation&quot;));
</del><ins>+        LValue result = nullptr;
</ins><span class="cx"> 
</span><del>-        LValue value = lowDouble(m_node-&gt;child1());
-        LValue integerValue = m_out.doubleCeil(value);
-        ValueFromBlock integerValueResult = m_out.anchor(integerValue);
</del><ins>+        if (producesInteger(m_node-&gt;arithRoundingMode()) &amp;&amp; !shouldCheckNegativeZero(m_node-&gt;arithRoundingMode())) {
+            LValue value = lowDouble(m_node-&gt;child1());
+            result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
+        } else {
+            LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, (&quot;ArithRound should round down&quot;));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;ArithRound continuation&quot;));
</ins><span class="cx"> 
</span><del>-        LValue realPart = m_out.doubleSub(integerValue, value);
</del><ins>+            LValue value = lowDouble(m_node-&gt;child1());
+            LValue integerValue = m_out.doubleCeil(value);
+            ValueFromBlock integerValueResult = m_out.anchor(integerValue);
</ins><span class="cx"> 
</span><del>-        m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
</del><ins>+            LValue realPart = m_out.doubleSub(integerValue, value);
</ins><span class="cx"> 
</span><del>-        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);
</del><ins>+            m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
</ins><span class="cx"> 
</span><del>-        LValue result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
</del><ins>+            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);
</ins><span class="cx"> 
</span><ins>+            result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
+        }
+
</ins><span class="cx">         if (producesInteger(m_node-&gt;arithRoundingMode())) {
</span><span class="cx">             LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node-&gt;arithRoundingMode()));
</span><span class="cx">             setInt32(integerValue);
</span><span class="lines">@@ -1916,6 +1929,26 @@
</span><span class="cx">             setDouble(result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileArithFloor()
+    {
+        LValue value = lowDouble(m_node-&gt;child1());
+        LValue integerValue = m_out.doubleFloor(value);
+        if (producesInteger(m_node-&gt;arithRoundingMode()))
+            setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node-&gt;arithRoundingMode())));
+        else
+            setDouble(integerValue);
+    }
+
+    void compileArithCeil()
+    {
+        LValue value = lowDouble(m_node-&gt;child1());
+        LValue integerValue = m_out.doubleCeil(value);
+        if (producesInteger(m_node-&gt;arithRoundingMode()))
+            setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node-&gt;arithRoundingMode())));
+        else
+            setDouble(integerValue);
+    }
+
</ins><span class="cx">     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node-&gt;child1()))); }
</span><span class="cx"> 
</span><span class="cx">     void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node-&gt;child1()))); }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -155,6 +155,7 @@
</span><span class="cx">     LValue mulWithOverflow64(LValue left, LValue right) { CRASH(); }
</span><span class="cx">     LValue doubleAbs(LValue value) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Abs, origin(), value); }
</span><span class="cx">     LValue doubleCeil(LValue operand) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Ceil, origin(), operand); }
</span><ins>+    LValue doubleFloor(LValue operand) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Floor, origin(), operand); }
</ins><span class="cx"> 
</span><span class="cx">     LValue doubleSin(LValue value)
</span><span class="cx">     {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/jit/ThunkGenerators.cpp (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -828,7 +828,7 @@
</span><span class="cx">     jit.returnInt32(SpecializedThunkJIT::regT0);
</span><span class="cx">     nonIntJump.link(&amp;jit);
</span><span class="cx">     jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
</span><del>-    if (jit.supportsFloatingPointCeil())
</del><ins>+    if (jit.supportsFloatingPointRounding())
</ins><span class="cx">         jit.ceilDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
</span><span class="cx">     else
</span><span class="cx">         jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(ceil));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathceilarithroundingmodejs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-arith-rounding-mode.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-arith-rounding-mode.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-arith-rounding-mode.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+function firstCareAboutZeroSecondDoesNot(a) {
+    var resultA = Math.ceil(a);
+    var resultB = Math.ceil(a)|0;
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstCareAboutZeroSecondDoesNot);
+
+function firstDoNotCareAboutZeroSecondDoes(a) {
+    var resultA = Math.ceil(a)|0;
+    var resultB = Math.ceil(a);
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstDoNotCareAboutZeroSecondDoes);
+
+// Warmup with doubles, but nothing that would ceil to -0 to ensure we never
+// see a double as result. The result must be integers, the input is kept to small values.
+function warmup() {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        firstCareAboutZeroSecondDoesNot(42.6 + i);
+        firstDoNotCareAboutZeroSecondDoes(42.4 + i);
+    }
+}
+warmup();
+
+function verifyNegativeZeroIsPreserved() {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        var result1 = firstCareAboutZeroSecondDoesNot(-0.1);
+        if (1 / result1.resultA !== -Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.1), resultA = &quot; + result1.resultA);
+        }
+        if (1 / result1.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.1), resultB = &quot; + result1.resultB);
+        }
+        var result2 = firstDoNotCareAboutZeroSecondDoes(-0.1);
+        if (1 / result2.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultA = &quot; + result1.resultA);
+        }
+        if (1 / result2.resultB !== -Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultB = &quot; + result1.resultB);
+        }
+        var result3 = firstCareAboutZeroSecondDoesNot(-0.0);
+        if (1 / result3.resultA !== -Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.0), resultA = &quot; + result3.resultA);
+        }
+        if (1 / result3.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.0), resultB = &quot; + result3.resultB);
+        }
+        var result4 = firstDoNotCareAboutZeroSecondDoes(-0.0);
+        if (1 / result4.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.0), resultA = &quot; + result4.resultA);
+        }
+        if (1 / result4.resultB !== -Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.0), resultB = &quot; + result4.resultB);
+        }
+        var result5 = firstCareAboutZeroSecondDoesNot(0.0);
+        if (1 / result5.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.0), resultA = &quot; + result5.resultA);
+        }
+        if (1 / result5.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.0), resultB = &quot; + result5.resultB);
+        }
+        var result6 = firstDoNotCareAboutZeroSecondDoes(0.0);
+        if (1 / result6.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.0), resultA = &quot; + result6.resultA);
+        }
+        if (1 / result6.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.0), resultB = &quot; + result6.resultB);
+        }
+        var result7 = firstCareAboutZeroSecondDoesNot(0.1);
+        if (1 / result7.resultA !== 1) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.1), resultA = &quot; + result7.resultA);
+        }
+        if (1 / result7.resultB !== 1) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.1), resultB = &quot; + result7.resultB);
+        }
+        var result8 = firstDoNotCareAboutZeroSecondDoes(0.1);
+        if (1 / result8.resultA !== 1) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.1), resultA = &quot; + result8.resultA);
+        }
+        if (1 / result8.resultB !== 1) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.1), resultB = &quot; + result8.resultB);
+        }
+    }
+}
+verifyNegativeZeroIsPreserved();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathceilbasicsjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-basics.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-basics.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-ceil-basics.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,257 @@
</span><ins>+
+function mathCeilOnIntegers(value)
+{
+    return Math.ceil(value);
+}
+noInline(mathCeilOnIntegers);
+
+function mathCeilOnDoubles(value)
+{
+    return Math.ceil(value);
+}
+noInline(mathCeilOnDoubles);
+
+function mathCeilOnBooleans(value)
+{
+    return Math.ceil(value);
+}
+noInline(mathCeilOnBooleans);
+
+// The trivial cases first.
+for (var i = 1; i &lt; 1e4; ++i) {
+    var ceiledValue = mathCeilOnIntegers(i);
+    if (ceiledValue !== i)
+        throw new Error(&quot;mathCeilOnIntegers(&quot; + i + &quot;) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnIntegers(-i);
+    if (ceiledValue !== -i)
+        throw new Error(&quot;mathCeilOnIntegers(&quot; + -i + &quot;) = &quot; + ceiledValue);
+
+    var doubleLow = i + 0.4;
+    var ceiledValue = mathCeilOnDoubles(doubleLow);
+    if (ceiledValue !== i + 1.0)
+        throw new Error(&quot;mathCeilOnDoubles(&quot; + doubleLow + &quot;) = &quot; + ceiledValue);
+
+    var doubleHigh = i + 0.6;
+    var ceiledValue = mathCeilOnDoubles(doubleHigh);
+    if (ceiledValue !== i + 1)
+        throw new Error(&quot;mathCeilOnDoubles(&quot; + doubleHigh + &quot;) = &quot; + ceiledValue);
+
+    var doubleMid = i + 0.5;
+    var ceiledValue = mathCeilOnDoubles(doubleMid);
+    if (ceiledValue !== i + 1)
+        throw new Error(&quot;mathCeilOnDoubles(&quot; + doubleMid + &quot;) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(-0.6);
+    if (ceiledValue !== -0.0)
+        throw new Error(&quot;mathCeilOnDoubles(-0.6) = &quot; + ceiledValue);
+}
+
+// Some more interesting cases, some of them well OSR exit when the return value is zero.
+for (var i = 0; i &lt; 1e4; ++i) {
+    var ceiledValue = mathCeilOnIntegers(i);
+    if (ceiledValue !== i)
+        throw new Error(&quot;mathCeilOnIntegers(&quot; + i + &quot;) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnIntegers(-i);
+    if (ceiledValue !== -i)
+        throw new Error(&quot;mathCeilOnIntegers(-&quot; + i + &quot;) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(-0.4);
+    if (ceiledValue !== 0)
+        throw new Error(&quot;mathCeilOnDoubles(-0.4) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(-0.5);
+    if (ceiledValue !== 0)
+        throw new Error(&quot;mathCeilOnDoubles(-0.5) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(-0);
+    if (!(ceiledValue === 0 &amp;&amp; (1/ceiledValue) === -Infinity))
+        throw new Error(&quot;mathCeilOnDoubles(-0) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(NaN);
+    if (ceiledValue === ceiledValue)
+        throw new Error(&quot;mathCeilOnDoubles(NaN) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(Number.POSITIVE_INFINITY);
+    if (ceiledValue !== Number.POSITIVE_INFINITY)
+        throw new Error(&quot;mathCeilOnDoubles(Number.POSITIVE_INFINITY) = &quot; + ceiledValue);
+
+    var ceiledValue = mathCeilOnDoubles(Number.NEGATIVE_INFINITY);
+    if (ceiledValue !== Number.NEGATIVE_INFINITY)
+        throw new Error(&quot;mathCeilOnDoubles(Number.NEGATIVE_INFINITY) = &quot; + ceiledValue);
+
+    var boolean = !!(i % 2);
+    var ceiledBoolean = mathCeilOnBooleans(boolean);
+    if (ceiledBoolean != boolean)
+        throw new Error(&quot;mathCeilOnDoubles(&quot; + boolean + &quot;) = &quot; + ceiledBoolean);
+}
+
+function uselessMathCeil(value)
+{
+    return Math.ceil(value|0);
+}
+noInline(uselessMathCeil);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var ceiledValue = uselessMathCeil(i);
+    if (ceiledValue !== i)
+        throw new Error(&quot;uselessMathCeil(&quot; + i + &quot;) = &quot; + ceiledValue);
+
+    var doubleLow = i + 0.4;
+    var ceiledValue = uselessMathCeil(doubleLow);
+    if (ceiledValue !== i)
+        throw new Error(&quot;uselessMathCeil(&quot; + doubleLow + &quot;) = &quot; + ceiledValue);
+
+    var doubleHigh = i + 0.6;
+    var ceiledValue = uselessMathCeil(doubleHigh);
+    if (ceiledValue !== i)
+        throw new Error(&quot;uselessMathCeil(&quot; + doubleHigh + &quot;) = &quot; + ceiledValue);
+
+    var doubleMid = i + 0.5;
+    var ceiledValue = uselessMathCeil(doubleMid);
+    if (ceiledValue !== i)
+        throw new Error(&quot;uselessMathCeil(&quot; + doubleMid + &quot;) = &quot; + ceiledValue);
+
+    var ceiledValue = uselessMathCeil(-0.4);
+    if (ceiledValue !== 0)
+        throw new Error(&quot;uselessMathCeil(-0.4) = &quot; + ceiledValue);
+
+    var ceiledValue = uselessMathCeil(-0.5);
+    if (ceiledValue !== 0)
+        throw new Error(&quot;uselessMathCeil(-0.5) = &quot; + ceiledValue);
+
+    var ceiledValue = uselessMathCeil(-0.6);
+    if (ceiledValue !== 0)
+        throw new Error(&quot;uselessMathCeil(-0.6) = &quot; + ceiledValue);
+}
+
+function mathCeilWithOverflow(value)
+{
+    return Math.ceil(value);
+}
+noInline(mathCeilWithOverflow);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var bigValue = 1000000000000;
+    var ceiledValue = mathCeilWithOverflow(bigValue);
+    if (ceiledValue !== bigValue)
+        throw new Error(&quot;mathCeilWithOverflow(&quot; + bigValue + &quot;) = &quot; + ceiledValue);
+}
+
+function mathCeilConsumedAsDouble(value)
+{
+    return Math.ceil(value) * 0.5;
+}
+noInline(mathCeilConsumedAsDouble);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var doubleValue = i + 0.1;
+    var ceiledValue = mathCeilConsumedAsDouble(doubleValue);
+    if (ceiledValue !== ((i + 1) * 0.5))
+        throw new Error(&quot;mathCeilConsumedAsDouble(&quot; + doubleValue + &quot;) = &quot; + ceiledValue);
+
+    var doubleValue = i + 0.6;
+    var ceiledValue = mathCeilConsumedAsDouble(doubleValue);
+    if (ceiledValue !== ((i + 1) * 0.5))
+        throw new Error(&quot;mathCeilConsumedAsDouble(&quot; + doubleValue + &quot;) = &quot; + ceiledValue);
+
+}
+
+function mathCeilDoesNotCareAboutMinusZero(value)
+{
+    return Math.ceil(value)|0;
+}
+noInline(mathCeilDoesNotCareAboutMinusZero);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var doubleMid = i + 0.5;
+    var ceiledValue = mathCeilDoesNotCareAboutMinusZero(doubleMid);
+    if (ceiledValue !== i + 1)
+        throw new Error(&quot;mathCeilDoesNotCareAboutMinusZero(&quot; + doubleMid + &quot;) = &quot; + ceiledValue);
+}
+
+
+// *** Function arguments. ***
+function mathCeilNoArguments()
+{
+    return Math.ceil();
+}
+noInline(mathCeilNoArguments);
+
+function mathCeilTooManyArguments(a, b, c)
+{
+    return Math.ceil(a, b, c);
+}
+noInline(mathCeilTooManyArguments);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathCeilNoArguments();
+    if (value === value)
+        throw new Error(&quot;mathCeilNoArguments() = &quot; + value);
+
+    var value = mathCeilTooManyArguments(2.1, 3, 5);
+    if (value !== 3)
+        throw new Error(&quot;mathCeilTooManyArguments() = &quot; + value);
+}
+
+
+// *** Constant as arguments. ***
+function testMathCeilOnConstants()
+{
+    var value = Math.ceil(0);
+    if (value !== 0)
+        throw new Error(&quot;Math.ceil(0) = &quot; + value);
+    var value = Math.ceil(-0);
+    if (!(value === 0 &amp;&amp; (1/value) === -Infinity))
+        throw new Error(&quot;Math.ceil(-0) = &quot; + value);
+    var value = Math.ceil(1);
+    if (value !== 1)
+        throw new Error(&quot;Math.ceil(1) = &quot; + value);
+    var value = Math.ceil(-1);
+    if (value !== -1)
+        throw new Error(&quot;Math.ceil(-1) = &quot; + value);
+    var value = Math.ceil(42);
+    if (value !== 42)
+        throw new Error(&quot;Math.ceil(42) = &quot; + value);
+    var value = Math.ceil(-42.2);
+    if (value !== -42)
+        throw new Error(&quot;Math.ceil(-42.2) = &quot; + value);
+    var value = Math.ceil(NaN);
+    if (value === value)
+        throw new Error(&quot;Math.ceil(NaN) = &quot; + value);
+    var value = Math.ceil(Number.POSITIVE_INFINITI);
+    if (value === value)
+        throw new Error(&quot;Math.ceil(Number.POSITIVE_INFINITI) = &quot; + value);
+    var value = Math.ceil(Number.NEGATIVE_INFINITI);
+    if (value === value)
+        throw new Error(&quot;Math.ceil(Number.NEGATIVE_INFINITI) = &quot; + value);
+    var value = Math.ceil(Math.E);
+    if (value !== 3)
+        throw new Error(&quot;Math.ceil(Math.E) = &quot; + value);
+}
+noInline(testMathCeilOnConstants);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    testMathCeilOnConstants();
+}
+
+
+// *** Struct transition. ***
+function mathCeilStructTransition(value)
+{
+    return Math.ceil(value);
+}
+noInline(mathCeilStructTransition);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathCeilStructTransition(42.5);
+    if (value !== 43)
+        throw new Error(&quot;mathCeilStructTransition(42.5) = &quot; + value);
+}
+
+Math.ceil = function() { return arguments[0] + 5; }
+
+var value = mathCeilStructTransition(42);
+if (value !== 47)
+    throw new Error(&quot;mathCeilStructTransition(42) after transition = &quot; + value);
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathfloorarithroundingmodejs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-arith-rounding-mode.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-arith-rounding-mode.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-arith-rounding-mode.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+function firstCareAboutZeroSecondDoesNot(a) {
+    var resultA = Math.floor(a);
+    var resultB = Math.floor(a)|0;
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstCareAboutZeroSecondDoesNot);
+
+function firstDoNotCareAboutZeroSecondDoes(a) {
+    var resultA = Math.floor(a)|0;
+    var resultB = Math.floor(a);
+    return { resultA:resultA, resultB:resultB };
+}
+noInline(firstDoNotCareAboutZeroSecondDoes);
+
+// Warmup with doubles, but nothing that would floor to -0 to ensure we never
+// see a double as result. The result must be integers, the input is kept to small values.
+function warmup() {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        firstCareAboutZeroSecondDoesNot(42.6 + i);
+        firstDoNotCareAboutZeroSecondDoes(42.4 + i);
+    }
+}
+warmup();
+
+function verifyNegativeZeroIsPreserved() {
+    for (var i = 0; i &lt; 1e4; ++i) {
+        var result1 = firstCareAboutZeroSecondDoesNot(-0.1);
+        if (1 / result1.resultA !== -1) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.1), resultA = &quot; + result1.resultA);
+        }
+        if (1 / result1.resultB !== -1) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.1), resultB = &quot; + result1.resultB);
+        }
+        var result2 = firstDoNotCareAboutZeroSecondDoes(-0.1);
+        if (1 / result2.resultA !== -1) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultA = &quot; + result1.resultA);
+        }
+        if (1 / result2.resultB !== -1) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.1), resultB = &quot; + result1.resultB);
+        }
+        var result3 = firstCareAboutZeroSecondDoesNot(-0.0);
+        if (1 / result3.resultA !== -Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.0), resultA = &quot; + result3.resultA);
+        }
+        if (1 / result3.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(-0.0), resultB = &quot; + result3.resultB);
+        }
+        var result4 = firstDoNotCareAboutZeroSecondDoes(-0.0);
+        if (1 / result4.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.0), resultA = &quot; + result4.resultA);
+        }
+        if (1 / result4.resultB !== -Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(-0.0), resultB = &quot; + result4.resultB);
+        }
+        var result5 = firstCareAboutZeroSecondDoesNot(0.0);
+        if (1 / result5.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.0), resultA = &quot; + result5.resultA);
+        }
+        if (1 / result5.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.0), resultB = &quot; + result5.resultB);
+        }
+        var result6 = firstDoNotCareAboutZeroSecondDoes(0.0);
+        if (1 / result6.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.0), resultA = &quot; + result6.resultA);
+        }
+        if (1 / result6.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.0), resultB = &quot; + result6.resultB);
+        }
+        var result7 = firstCareAboutZeroSecondDoesNot(0.1);
+        if (1 / result7.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.1), resultA = &quot; + result7.resultA);
+        }
+        if (1 / result7.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstCareAboutZeroSecondDoesNot(0.1), resultB = &quot; + result7.resultB);
+        }
+        var result8 = firstDoNotCareAboutZeroSecondDoes(0.1);
+        if (1 / result8.resultA !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.1), resultA = &quot; + result8.resultA);
+        }
+        if (1 / result8.resultB !== Infinity) {
+            throw new Error(&quot;Failed firstDoNotCareAboutZeroSecondDoes(0.1), resultB = &quot; + result8.resultB);
+        }
+    }
+}
+verifyNegativeZeroIsPreserved();
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathfloorbasicsjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-basics.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-basics.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-floor-basics.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,257 @@
</span><ins>+
+function mathFloorOnIntegers(value)
+{
+    return Math.floor(value);
+}
+noInline(mathFloorOnIntegers);
+
+function mathFloorOnDoubles(value)
+{
+    return Math.floor(value);
+}
+noInline(mathFloorOnDoubles);
+
+function mathFloorOnBooleans(value)
+{
+    return Math.floor(value);
+}
+noInline(mathFloorOnBooleans);
+
+// The trivial cases first.
+for (var i = 1; i &lt; 1e4; ++i) {
+    var flooredValue = mathFloorOnIntegers(i);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorOnIntegers(&quot; + i + &quot;) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnIntegers(-i);
+    if (flooredValue !== -i)
+        throw new Error(&quot;mathFloorOnIntegers(&quot; + -i + &quot;) = &quot; + flooredValue);
+
+    var doubleLow = i + 0.4;
+    var flooredValue = mathFloorOnDoubles(doubleLow);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorOnDoubles(&quot; + doubleLow + &quot;) = &quot; + flooredValue);
+
+    var doubleHigh = i + 0.6;
+    var flooredValue = mathFloorOnDoubles(doubleHigh);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorOnDoubles(&quot; + doubleHigh + &quot;) = &quot; + flooredValue);
+
+    var doubleMid = i + 0.5;
+    var flooredValue = mathFloorOnDoubles(doubleMid);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorOnDoubles(&quot; + doubleMid + &quot;) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(-0.6);
+    if (flooredValue !== -1.0)
+        throw new Error(&quot;mathFloorOnDoubles(-0.6) = &quot; + flooredValue);
+}
+
+// Some more interesting cases, some of them well OSR exit when the return value is zero.
+for (var i = 0; i &lt; 1e4; ++i) {
+    var flooredValue = mathFloorOnIntegers(i);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorOnIntegers(&quot; + i + &quot;) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnIntegers(-i);
+    if (flooredValue !== -i)
+        throw new Error(&quot;mathFloorOnIntegers(-&quot; + i + &quot;) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(-0.4);
+    if (flooredValue !== -1.00)
+        throw new Error(&quot;mathFloorOnDoubles(-0.4) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(-0.5);
+    if (flooredValue !== -1.0)
+        throw new Error(&quot;mathFloorOnDoubles(-0.5) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(-0);
+    if (!(flooredValue === 0 &amp;&amp; (1/flooredValue) === -Infinity))
+        throw new Error(&quot;mathFloorOnDoubles(-0) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(NaN);
+    if (flooredValue === flooredValue)
+        throw new Error(&quot;mathFloorOnDoubles(NaN) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(Number.POSITIVE_INFINITY);
+    if (flooredValue !== Number.POSITIVE_INFINITY)
+        throw new Error(&quot;mathFloorOnDoubles(Number.POSITIVE_INFINITY) = &quot; + flooredValue);
+
+    var flooredValue = mathFloorOnDoubles(Number.NEGATIVE_INFINITY);
+    if (flooredValue !== Number.NEGATIVE_INFINITY)
+        throw new Error(&quot;mathFloorOnDoubles(Number.NEGATIVE_INFINITY) = &quot; + flooredValue);
+
+    var boolean = !!(i % 2);
+    var flooredBoolean = mathFloorOnBooleans(boolean);
+    if (flooredBoolean != boolean)
+        throw new Error(&quot;mathFloorOnDoubles(&quot; + boolean + &quot;) = &quot; + flooredBoolean);
+}
+
+function uselessMathFloor(value)
+{
+    return Math.floor(value|0);
+}
+noInline(uselessMathFloor);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var flooredValue = uselessMathFloor(i);
+    if (flooredValue !== i)
+        throw new Error(&quot;uselessMathFloor(&quot; + i + &quot;) = &quot; + flooredValue);
+
+    var doubleLow = i + 0.4;
+    var flooredValue = uselessMathFloor(doubleLow);
+    if (flooredValue !== i)
+        throw new Error(&quot;uselessMathFloor(&quot; + doubleLow + &quot;) = &quot; + flooredValue);
+
+    var doubleHigh = i + 0.6;
+    var flooredValue = uselessMathFloor(doubleHigh);
+    if (flooredValue !== i)
+        throw new Error(&quot;uselessMathFloor(&quot; + doubleHigh + &quot;) = &quot; + flooredValue);
+
+    var doubleMid = i + 0.5;
+    var flooredValue = uselessMathFloor(doubleMid);
+    if (flooredValue !== i)
+        throw new Error(&quot;uselessMathFloor(&quot; + doubleMid + &quot;) = &quot; + flooredValue);
+
+    var flooredValue = uselessMathFloor(-0.4);
+    if (flooredValue !== 0)
+        throw new Error(&quot;uselessMathFloor(-0.4) = &quot; + flooredValue);
+
+    var flooredValue = uselessMathFloor(-0.5);
+    if (flooredValue !== 0)
+        throw new Error(&quot;uselessMathFloor(-0.5) = &quot; + flooredValue);
+
+    var flooredValue = uselessMathFloor(-0.6);
+    if (flooredValue !== 0)
+        throw new Error(&quot;uselessMathFloor(-0.6) = &quot; + flooredValue);
+}
+
+function mathFloorWithOverflow(value)
+{
+    return Math.floor(value);
+}
+noInline(mathFloorWithOverflow);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var bigValue = 1000000000000;
+    var flooredValue = mathFloorWithOverflow(bigValue);
+    if (flooredValue !== bigValue)
+        throw new Error(&quot;mathFloorWithOverflow(&quot; + bigValue + &quot;) = &quot; + flooredValue);
+}
+
+function mathFloorConsumedAsDouble(value)
+{
+    return Math.floor(value) * 0.5;
+}
+noInline(mathFloorConsumedAsDouble);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var doubleValue = i + 0.1;
+    var flooredValue = mathFloorConsumedAsDouble(doubleValue);
+    if (flooredValue !== (i * 0.5))
+        throw new Error(&quot;mathFloorConsumedAsDouble(&quot; + doubleValue + &quot;) = &quot; + flooredValue);
+
+    var doubleValue = i + 0.6;
+    var flooredValue = mathFloorConsumedAsDouble(doubleValue);
+    if (flooredValue !== (i * 0.5))
+        throw new Error(&quot;mathFloorConsumedAsDouble(&quot; + doubleValue + &quot;) = &quot; + flooredValue);
+
+}
+
+function mathFloorDoesNotCareAboutMinusZero(value)
+{
+    return Math.floor(value)|0;
+}
+noInline(mathFloorDoesNotCareAboutMinusZero);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var doubleMid = i + 0.5;
+    var flooredValue = mathFloorDoesNotCareAboutMinusZero(doubleMid);
+    if (flooredValue !== i)
+        throw new Error(&quot;mathFloorDoesNotCareAboutMinusZero(&quot; + doubleMid + &quot;) = &quot; + flooredValue);
+}
+
+
+// *** Function arguments. ***
+function mathFloorNoArguments()
+{
+    return Math.floor();
+}
+noInline(mathFloorNoArguments);
+
+function mathFloorTooManyArguments(a, b, c)
+{
+    return Math.floor(a, b, c);
+}
+noInline(mathFloorTooManyArguments);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathFloorNoArguments();
+    if (value === value)
+        throw new Error(&quot;mathFloorNoArguments() = &quot; + value);
+
+    var value = mathFloorTooManyArguments(2.1, 3, 5);
+    if (value !== 2)
+        throw new Error(&quot;mathFloorTooManyArguments() = &quot; + value);
+}
+
+
+// *** Constant as arguments. ***
+function testMathFloorOnConstants()
+{
+    var value = Math.floor(0);
+    if (value !== 0)
+        throw new Error(&quot;Math.floor(0) = &quot; + value);
+    var value = Math.floor(-0);
+    if (!(value === 0 &amp;&amp; (1/value) === -Infinity))
+        throw new Error(&quot;Math.floor(-0) = &quot; + value);
+    var value = Math.floor(1);
+    if (value !== 1)
+        throw new Error(&quot;Math.floor(1) = &quot; + value);
+    var value = Math.floor(-1);
+    if (value !== -1)
+        throw new Error(&quot;Math.floor(-1) = &quot; + value);
+    var value = Math.floor(42);
+    if (value !== 42)
+        throw new Error(&quot;Math.floor(42) = &quot; + value);
+    var value = Math.floor(-42.2);
+    if (value !== -43)
+        throw new Error(&quot;Math.floor(-42.2) = &quot; + value);
+    var value = Math.floor(NaN);
+    if (value === value)
+        throw new Error(&quot;Math.floor(NaN) = &quot; + value);
+    var value = Math.floor(Number.POSITIVE_INFINITI);
+    if (value === value)
+        throw new Error(&quot;Math.floor(Number.POSITIVE_INFINITI) = &quot; + value);
+    var value = Math.floor(Number.NEGATIVE_INFINITI);
+    if (value === value)
+        throw new Error(&quot;Math.floor(Number.NEGATIVE_INFINITI) = &quot; + value);
+    var value = Math.floor(Math.E);
+    if (value !== 2)
+        throw new Error(&quot;Math.floor(Math.E) = &quot; + value);
+}
+noInline(testMathFloorOnConstants);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    testMathFloorOnConstants();
+}
+
+
+// *** Struct transition. ***
+function mathFloorStructTransition(value)
+{
+    return Math.floor(value);
+}
+noInline(mathFloorStructTransition);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var value = mathFloorStructTransition(42.5);
+    if (value !== 42)
+        throw new Error(&quot;mathFloorStructTransition(42.5) = &quot; + value);
+}
+
+Math.floor = function() { return arguments[0] + 5; }
+
+var value = mathFloorStructTransition(42);
+if (value !== 47)
+    throw new Error(&quot;mathFloorStructTransition(42) after transition = &quot; + value);
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundshouldnotusetruncatejs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-round-should-not-use-truncate.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-round-should-not-use-truncate.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-round-should-not-use-truncate.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+function mathRoundDoesNotCareAboutMinusZero(value)
+{
+    return Math.round(value);
+}
+noInline(mathRoundDoesNotCareAboutMinusZero);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    var doubleMid = -9901 - 0.6;
+    var roundedValue = mathRoundDoesNotCareAboutMinusZero(doubleMid);
+    if (roundedValue !== -9902)
+        throw &quot;mathRoundDoesNotCareAboutMinusZero(&quot; + doubleMid + &quot;) = &quot; + roundedValue;
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundinginfinityjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-infinity.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-infinity.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-infinity.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testRound(value)
+{
+    return Math.round(value);
+}
+noInline(testRound);
+
+function testFloor(value)
+{
+    return Math.floor(value);
+}
+noInline(testFloor);
+
+function testCeil(value)
+{
+    return Math.ceil(value);
+}
+noInline(testCeil);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(testRound(Infinity), Infinity);
+    shouldBe(testRound(-Infinity), -Infinity);
+    shouldBe(testFloor(Infinity), Infinity);
+    shouldBe(testFloor(-Infinity), -Infinity);
+    shouldBe(testCeil(Infinity), Infinity);
+    shouldBe(testCeil(-Infinity), -Infinity);
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundingnanjs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-nan.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-nan.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-nan.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testRound(value)
+{
+    return Math.round(value);
+}
+noInline(testRound);
+
+function testFloor(value)
+{
+    return Math.floor(value);
+}
+noInline(testFloor);
+
+function testCeil(value)
+{
+    return Math.ceil(value);
+}
+noInline(testCeil);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(Number.isNaN(testRound(NaN)), true);
+    shouldBe(Number.isNaN(testFloor(NaN)), true);
+    shouldBe(Number.isNaN(testCeil(NaN)), true);
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoretestsstressmathroundingnegativezerojs"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-negative-zero.js (0 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-negative-zero.js                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/tests/stress/math-rounding-negative-zero.js        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function testRound(value)
+{
+    return Math.round(value);
+}
+noInline(testRound);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(1 / testRound(-0.4), -Infinity);
+    shouldBe(1 / testRound(-0.5), -Infinity);
+    shouldBe(1 / testRound(-0.6), -1.0);
+    shouldBe(1 / testRound(-0.0), -Infinity);
+    shouldBe(1 / testRound(0.1), Infinity);
+}
+
+function testFloor(value)
+{
+    return Math.floor(value);
+}
+noInline(testFloor);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(1 / testFloor(-0.0), -Infinity);
+}
+
+function testCeil(value)
+{
+    return Math.ceil(value);
+}
+noInline(testCeil);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(1 / testCeil(-0.0), -Infinity);
+    shouldBe(1 / testCeil(-0.9), -Infinity);
+}
+
+function testRoundNonNegativeZero(value)
+{
+    return Math.round(value) | 0;
+}
+noInline(testRoundNonNegativeZero);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(testRoundNonNegativeZero(0.4), 0);
+    shouldBe(testRoundNonNegativeZero(0.5), 1);
+    shouldBe(testRoundNonNegativeZero(0.6), 1);
+    shouldBe(testRoundNonNegativeZero(0.0), 0);
+    shouldBe(testRoundNonNegativeZero(0.1), 0);
+}
+shouldBe(1 / testRoundNonNegativeZero(-0.4), Infinity);
+
+function testRoundNonNegativeZero2(value)
+{
+    return Math.round(value) | 0;
+}
+noInline(testRoundNonNegativeZero2);
+
+for (var i = 0; i &lt; 1e4; ++i) {
+    shouldBe(1 / testRoundNonNegativeZero2(-0.4), Infinity);
+    shouldBe(1 / testRoundNonNegativeZero2(-0.5), Infinity);
+    shouldBe(1 / testRoundNonNegativeZero2(-0.6), -1.0);
+    shouldBe(1 / testRoundNonNegativeZero2(-0.0), Infinity);
+    shouldBe(1 / testRoundNonNegativeZero2(0.1), Infinity);
+}
+
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212WebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Websites/webkit.org/ChangeLog (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Websites/webkit.org/ChangeLog        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Websites/webkit.org/ChangeLog        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-02-29  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [DFG][FTL][B3] Support floor and ceil
+        https://bugs.webkit.org/show_bug.cgi?id=154683
+
+        Reviewed by Filip Pizlo.
+
+        * docs/b3/intermediate-representation.html:
+
</ins><span class="cx"> 2016-02-16  Jonathan Davis  &lt;jond@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a redirect for B3 documentation
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212Websiteswebkitorgdocsb3intermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Websites/webkit.org/docs/b3/intermediate-representation.html (197670 => 197671)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-03-07 10:45:06 UTC (rev 197670)
+++ releases/WebKitGTK/webkit-2.12/Websites/webkit.org/docs/b3/intermediate-representation.html        2016-03-07 11:08:22 UTC (rev 197671)
</span><span class="lines">@@ -272,6 +272,9 @@
</span><span class="cx">       &lt;dt&gt;T Ceil(T)&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;Ceiling.  Valid for Float and Double.&lt;/dd&gt;
</span><span class="cx"> 
</span><ins>+      &lt;dt&gt;T Floor(T)&lt;/dt&gt;
+      &lt;dd&gt;Flooring.  Valid for Float and Double.&lt;/dd&gt;
+
</ins><span class="cx">       &lt;dt&gt;T Sqrt(T)&lt;/dt&gt;
</span><span class="cx">       &lt;dd&gt;Square root.  Valid for Float and Double.&lt;/dd&gt;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>