Modified: trunk/JSTests/ChangeLog (232566 => 232567)
--- trunk/JSTests/ChangeLog 2018-06-07 00:57:34 UTC (rev 232566)
+++ trunk/JSTests/ChangeLog 2018-06-07 02:28:01 UTC (rev 232567)
@@ -1,3 +1,17 @@
+2018-06-06 Yusuke Suzuki <utatane....@gmail.com>
+
+ [DFG] Compare operations do not respect negative zeros
+ https://bugs.webkit.org/show_bug.cgi?id=183729
+
+ Reviewed by Saam Barati.
+
+ * stress/comparison-ignore-negative-zero.js: Added.
+ (shouldBe):
+ (zero):
+ (negativeZero):
+ (object.valueOf):
+ (test):
+
2018-06-06 Saam Barati <sbar...@apple.com>
generateConditionsForInstanceOf needs to see if the object has a poly proto structure before assuming it has a constant prototype
Added: trunk/JSTests/stress/comparison-ignore-negative-zero.js (0 => 232567)
--- trunk/JSTests/stress/comparison-ignore-negative-zero.js (rev 0)
+++ trunk/JSTests/stress/comparison-ignore-negative-zero.js 2018-06-07 02:28:01 UTC (rev 232567)
@@ -0,0 +1,65 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + String(actual) + ' ' + String(expected));
+}
+noInline(shouldBe);
+
+function zero()
+{
+ return 0;
+}
+noInline(zero);
+
+function negativeZero()
+{
+ return -0;
+}
+noInline(negativeZero);
+
+var object = {
+ valueOf()
+ {
+ return -0;
+ }
+};
+
+function test()
+{
+ shouldBe(0 < zero(), false);
+ shouldBe(0 < (-zero()), false);
+ shouldBe(0 <= zero(), true);
+ shouldBe(0 <= (-zero()), true);
+ shouldBe(0 > zero(), false);
+ shouldBe(0 > (-zero()), false);
+ shouldBe(0 >= zero(), true);
+ shouldBe(0 >= (-zero()), true);
+ shouldBe(0 == zero(), true);
+ shouldBe(0 == (-zero()), true);
+ shouldBe(0 === zero(), true);
+ shouldBe(0 === (-zero()), true);
+ shouldBe(0 != zero(), false);
+ shouldBe(0 != (-zero()), false);
+ shouldBe(0 !== zero(), false);
+ shouldBe(0 !== (-zero()), false);
+
+ shouldBe(0 < object, false);
+ shouldBe(0 < -object, false);
+ shouldBe(0 <= object, true);
+ shouldBe(0 <= -object, true);
+ shouldBe(0 > object, false);
+ shouldBe(0 > -object, false);
+ shouldBe(0 >= object, true);
+ shouldBe(0 >= -object, true);
+ shouldBe(0 == object, true);
+ shouldBe(0 == -object, true);
+ shouldBe(0 === object, false);
+ shouldBe(0 === -object, true);
+ shouldBe(0 != object, false);
+ shouldBe(0 != -object, false);
+ shouldBe(0 !== object, true);
+ shouldBe(0 !== -object, false);
+}
+noInline(test);
+
+for (var i = 0; i < 1e5; ++i)
+ test();
Modified: trunk/Source/_javascript_Core/ChangeLog (232566 => 232567)
--- trunk/Source/_javascript_Core/ChangeLog 2018-06-07 00:57:34 UTC (rev 232566)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-06-07 02:28:01 UTC (rev 232567)
@@ -1,3 +1,27 @@
+2018-06-06 Yusuke Suzuki <utatane....@gmail.com>
+
+ [DFG] Compare operations do not respect negative zeros
+ https://bugs.webkit.org/show_bug.cgi?id=183729
+
+ Reviewed by Saam Barati.
+
+ Compare operations do not respect negative zeros. So propagating this can
+ reduce the size of the produced code for negative zero case. This pattern
+ can be seen in Kraken stanford-crypto-aes.
+
+ This also causes an existing bug which converts CompareEq(Int32Only, NonIntAsdouble) to false.
+ However, NonIntAsdouble includes negative zero, which can be equal to Int32 positive zero.
+ This issue is covered by fold-based-on-int32-proof-mul-branch.js, and we fix this.
+
+ * bytecode/SpeculatedType.cpp:
+ (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations):
+ SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0.
+ To emphasize this, we use SpecAnyIntAsDouble | SpecNonIntAsDouble directly instead of
+ SpecDoubleReal.
+
+ * dfg/DFGBackwardsPropagationPhase.cpp:
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+
2018-06-06 Saam Barati <sbar...@apple.com>
generateConditionsForInstanceOf needs to see if the object has a poly proto structure before assuming it has a constant prototype
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (232566 => 232567)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2018-06-07 00:57:34 UTC (rev 232566)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2018-06-07 02:28:01 UTC (rev 232567)
@@ -567,8 +567,10 @@
SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
{
- if (type & (SpecAnyInt | SpecAnyIntAsDouble))
- type |= (SpecAnyInt | SpecAnyIntAsDouble);
+ // SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0 in the context of == and ===.
+ if (type & (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble))
+ type |= (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble);
+
if (type & SpecString)
type |= SpecString;
return type;
Modified: trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp (232566 => 232567)
--- trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2018-06-07 00:57:34 UTC (rev 232566)
+++ trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2018-06-07 02:28:01 UTC (rev 232567)
@@ -388,6 +388,19 @@
break;
}
+ case CompareLess:
+ case CompareLessEq:
+ case CompareGreater:
+ case CompareGreaterEq:
+ case CompareBelow:
+ case CompareBelowEq:
+ case CompareEq:
+ case CompareStrictEq: {
+ node->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
+ node->child2()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsOther);
+ break;
+ }
+
case PutByValDirect:
case PutByVal: {
m_graph.varArgChild(node, 0)->mergeFlags(NodeBytecodeUsesAsValue);