Modified: trunk/JSTests/ChangeLog (264574 => 264575)
--- trunk/JSTests/ChangeLog 2020-07-18 23:09:56 UTC (rev 264574)
+++ trunk/JSTests/ChangeLog 2020-07-19 04:24:20 UTC (rev 264575)
@@ -1,3 +1,18 @@
+2020-07-18 Mark Lam <[email protected]>
+
+ Fixed regression due to r264507: Math.{min|max} inequality test should use DoubleNotEqualOrUnordered instead DoubleNotEqualAndOrdered.
+ https://bugs.webkit.org/show_bug.cgi?id=214526
+ <rdar://problem/65778061>
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/math-max-min.js: Added.
+ (isNegativeZero):
+ (numberAsString):
+ (testMax):
+ (testMin):
+ (assertEq):
+
2020-07-18 Alexey Shvayka <[email protected]>
Redefining a property should not change its insertion index (Object.keys order)
Added: trunk/JSTests/stress/math-max-min.js (0 => 264575)
--- trunk/JSTests/stress/math-max-min.js (rev 0)
+++ trunk/JSTests/stress/math-max-min.js 2020-07-19 04:24:20 UTC (rev 264575)
@@ -0,0 +1,118 @@
+//@ runDefault("--useConcurrentJIT=false")
+
+let operands = [
+ 0,
+ -0,
+ 1,
+ -1,
+ 42,
+ -42,
+ -Number.EPSILON,
+ Number.EPSILON,
+ -Number.MIN_VALUE,
+ Number.MIN_VALUE,
+ -Number.MAX_VALUE,
+ Number.MAX_VALUE,
+ Number.MIN_SAFE_INTEGER,
+ Number.MAX_SAFE_INTEGER,
+ Number.NEGATIVE_INFINITY,
+ Number.POSITIVE_INFINITY,
+ Number.NaN,
+];
+
+function isNegativeZero(x) {
+ if (x != 0)
+ return false;
+ return (1/x == Number.NEGATIVE_INFINITY);
+}
+
+let expectedMaxResults = [];
+for (i in operands) {
+ expectedMaxResults[i] = [];
+ for (j in operands) {
+ let x = operands[i];
+ let y = operands[j];
+ let result;
+ if (Number.isNaN(x) || Number.isNaN(y))
+ result = Number.NaN;
+ else if (x == y)
+ result = isNegativeZero(x) ? y : x;
+ else
+ result = (x > y) ? x : y;
+ expectedMaxResults[i][j] = result;
+ }
+}
+
+let expectedMinResults = [];
+for (i in operands) {
+ expectedMinResults[i] = [];
+ for (j in operands) {
+ let x = operands[i];
+ let y = operands[j];
+ let result;
+ if (Number.isNaN(x) || Number.isNaN(y))
+ result = Number.NaN;
+ else if (x == y)
+ result = isNegativeZero(x) ? x : y;
+ else
+ result = (x < y) ? x : y;
+ expectedMinResults[i][j] = result;
+ }
+}
+
+function numberAsString(x) {
+ if (x == 0 && isNegativeZero(x))
+ return "-0";
+ return x;
+}
+
+function testMax(x, y) {
+ return Math.max(x, y);
+}
+noInline(testMax);
+
+function testMin(x, y) {
+ return Math.min(x, y);
+}
+noInline(testMin);
+
+let numberOfFailures = 0;
+
+function assertEq(label, x, y, expected, actual) {
+ if (Number.isNaN(expected) && Number.isNaN(actual))
+ return;
+
+ if ((actual == expected) && (actual == 0)) {
+ if (isNegativeZero(expected) != isNegativeZero(actual)) {
+ print("FAIL " + label + ": comparing " + numberAsString(x) + " and " + numberAsString(y) + ": expected: " + numberAsString(expected) + " actual: " + numberAsString(actual));
+ numberOfFailures++;
+ return;
+ }
+ }
+
+ if (expected !== actual) {
+ print("FAIL " + label + ": comparing " + numberAsString(x) + " and " + numberAsString(y) + ": expected: " + numberAsString(expected) + " actual: " + numberAsString(actual));
+ numberOfFailures++;
+ return;
+ }
+}
+
+for (var iteration = 0; iteration < 1000; ++iteration) {
+ for (i in operands) {
+ for (j in operands) {
+ let x = operands[i];
+ let y = operands[j];
+
+ let maxResult = testMax(x, y);
+ let expectedMaxResult = expectedMaxResults[i][j];
+ assertEq("Math.max", x, y, expectedMaxResult, maxResult);
+
+ let minResult = testMin(x, y);
+ let expectedMinResult = expectedMinResults[i][j];
+ assertEq("Math.min", x, y, expectedMinResult, minResult);
+ }
+ }
+}
+
+if (numberOfFailures > 0)
+ throw "FAILED";
Modified: trunk/Source/_javascript_Core/ChangeLog (264574 => 264575)
--- trunk/Source/_javascript_Core/ChangeLog 2020-07-18 23:09:56 UTC (rev 264574)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-07-19 04:24:20 UTC (rev 264575)
@@ -1,3 +1,17 @@
+2020-07-18 Mark Lam <[email protected]>
+
+ Fixed regression due to r264507: Math.{min|max} inequality test should use DoubleNotEqualOrUnordered instead DoubleNotEqualAndOrdered.
+ https://bugs.webkit.org/show_bug.cgi?id=214526
+ <rdar://problem/65778061>
+
+ Reviewed by Yusuke Suzuki.
+
+ This bug resulted in NaNs being handled by the "equal" case in some scenarios,
+ which resulted in an assertion failure in a ValueRep on an internal test.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileArithMinMax):
+
2020-07-18 Alexey Shvayka <[email protected]>
Redefining a property should not change its insertion index (Object.keys order)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (264574 => 264575)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-07-18 23:09:56 UTC (rev 264574)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-07-19 04:24:20 UTC (rev 264575)
@@ -6181,7 +6181,7 @@
MacroAssembler::JumpList done;
MacroAssembler::Jump op1Less = m_jit.branchDouble(node->op() == ArithMin ? MacroAssembler::DoubleLessThanAndOrdered : MacroAssembler::DoubleGreaterThanAndOrdered, op1FPR, op2FPR);
- MacroAssembler::Jump opNotEqual = m_jit.branchDouble(MacroAssembler::DoubleNotEqualAndOrdered, op1FPR, op2FPR);
+ MacroAssembler::Jump opNotEqualOrUnordered = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, op1FPR, op2FPR);
// The spec for Math.min and Math.max states that +0 is considered to be larger than -0.
if (node->op() == ArithMin)
@@ -6191,11 +6191,11 @@
done.append(m_jit.jump());
- opNotEqual.link(&m_jit);
+ opNotEqualOrUnordered.link(&m_jit);
// op2 is either the lesser one or one of then is NaN
MacroAssembler::Jump op2Less = m_jit.branchDouble(node->op() == ArithMin ? MacroAssembler::DoubleGreaterThanAndOrdered : MacroAssembler::DoubleLessThanAndOrdered, op1FPR, op2FPR);
- // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
+ // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
// op1 + op2 and putting it into result.
m_jit.addDouble(op1FPR, op2FPR, resultFPR);
done.append(m_jit.jump());