13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without
33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are
43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met:
53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions of source code must retain the above copyright
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       notice, this list of conditions and the following disclaimer.
83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions in binary form must reproduce the above
93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       copyright notice, this list of conditions and the following
103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       disclaimer in the documentation and/or other materials provided
113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       with the distribution.
123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Neither the name of Google Inc. nor the names of its
133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       contributors may be used to endorse or promote products derived
143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       from this software without specific prior written permission.
153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Flags: --max-new-space-size=256 --allow-natives-syntax
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test inlining of Math.floor when assigned to a local.
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar test_id = 0;
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction testFloor(expect, input) {
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var test = new Function('n',
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          '"' + (test_id++) +
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          '";var f = Math.floor; return f(n)');
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(expect, test(input));
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(expect, test(input));
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(expect, test(input));
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %OptimizeFunctionOnNextCall(test);
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(expect, test(input));
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction zero() {
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var x = 0.5;
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (function() { return x - 0.5; })();
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction test() {
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, 0);
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, zero());
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-0, -0);
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(Infinity, Infinity);
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-Infinity, -Infinity);
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(NaN, NaN);
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Ensure that a negative zero coming from Math.floor is properly handled
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // by other operations.
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  function ifloor(x) {
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return 1 / Math.floor(x);
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(-Infinity, ifloor(-0));
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(-Infinity, ifloor(-0));
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(-Infinity, ifloor(-0));
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %OptimizeFunctionOnNextCall(ifloor);
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(-Infinity, ifloor(-0));
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, 0.1);
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, 0.49999999999999994);
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, 0.5);
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, 0.7);
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -0.1);
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -0.49999999999999994);
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -0.5);
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -0.7);
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(1, 1);
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(1, 1.1);
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(1, 1.5);
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(1, 1.7);
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -1);
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-2, -1.1);
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-2, -1.5);
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-2, -1.7);
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(0, Number.MIN_VALUE);
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-1, -Number.MIN_VALUE);
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(Infinity, Infinity);
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-Infinity, -Infinity);
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 2^30 is a smi boundary.
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var two_30 = 1 << 30;
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30, two_30);
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30, two_30 + 0.1);
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30, two_30 + 0.5);
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30, two_30 + 0.7);
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30 - 1, two_30 - 1);
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30 - 1, two_30 - 1 + 0.1);
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30 - 1, two_30 - 1 + 0.5);
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_30 - 1, two_30 - 1 + 0.7);
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30, -two_30);
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30, -two_30 + 0.1);
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30, -two_30 + 0.5);
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30, -two_30 + 0.7);
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30 + 1, -two_30 + 1);
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 2^52 is a precision boundary.
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var two_52 = (1 << 30) * (1 << 22);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52, two_52);
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52, two_52 + 0.1);
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(two_52, two_52 + 0.5);
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52, two_52 + 0.5);
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  assertEquals(two_52 + 1, two_52 + 0.7);
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52 + 1, two_52 + 0.7);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52 - 1, two_52 - 1);
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52 - 1, two_52 - 1 + 0.1);
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52 - 1, two_52 - 1 + 0.5);
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(two_52 - 1, two_52 - 1 + 0.7);
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52, -two_52);
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52, -two_52 + 0.1);
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52, -two_52 + 0.5);
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52, -two_52 + 0.7);
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52 + 1, -two_52 + 1);
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test in a loop to cover the custom IC and GC-related issues.
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfor (var i = 0; i < 50; i++) {
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  test();
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Regression test for a bug where a negative zero coming from Math.floor
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// was not properly handled by other operations.
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction floorsum(i, n) {
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var ret = Math.floor(n);
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (--i > 0) {
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ret += Math.floor(n);
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ret;
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(-0, floorsum(1, -0));
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch%OptimizeFunctionOnNextCall(floorsum);
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The optimized function will deopt.  Run it with enough iterations to try
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// to optimize via OSR (triggering the bug).
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(-0, floorsum(100000, -0));
162