Changeset 260512 in webkit
- Timestamp:
- Apr 22, 2020 8:40:06 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 14 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r260490 r260512 1 2020-04-22 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] AI results of BigInt32 Bitwise shift operation does not match to runtime results 4 https://bugs.webkit.org/show_bug.cgi?id=210839 5 6 Reviewed by Saam Barati. 7 8 * stress/v8-bigint32-add.js: Added. 9 (main): 10 * stress/v8-bigint32-and.js: Added. 11 (main): 12 * stress/v8-bigint32-dec.js: Added. 13 (main): 14 * stress/v8-bigint32-div.js: Added. 15 (main): 16 * stress/v8-bigint32-inc.js: Added. 17 (main): 18 * stress/v8-bigint32-mod.js: Added. 19 (main): 20 * stress/v8-bigint32-mul.js: Added. 21 (main): 22 * stress/v8-bigint32-neg.js: Added. 23 (main): 24 * stress/v8-bigint32-not.js: Added. 25 (main): 26 * stress/v8-bigint32-or.js: Added. 27 (main): 28 * stress/v8-bigint32-sar.js: Added. 29 (main): 30 * stress/v8-bigint32-shl.js: Added. 31 (main): 32 * stress/v8-bigint32-sub.js: Added. 33 (main): 34 * stress/v8-bigint32-xor.js: Added. 35 (main): 36 1 37 2020-04-21 Yusuke Suzuki <ysuzuki@apple.com> 2 38 -
trunk/Source/JavaScriptCore/ChangeLog
r260501 r260512 1 2020-04-22 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] AI results of BigInt32 Bitwise shift operation does not match to runtime results 4 https://bugs.webkit.org/show_bug.cgi?id=210839 5 6 Reviewed by Saam Barati. 7 8 While runtime function of bitwise ops with BigInt32 sometimes returns HeapBigInt, DFG AI is setting SpecBigInt32 9 as a result value. This leads to miscompilation particularly in FTL since FTL uses this information to remove 10 a lot of branches. 11 12 And we found that FTL BigInt32 predicate is not correctly checking state. This patch fixes it too. 13 14 Added test case found this (v8-bigint32-sar.js). 15 16 * dfg/DFGAbstractInterpreterInlines.h: 17 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 18 * ftl/FTLLowerDFGToB3.cpp: 19 (JSC::FTL::DFG::LowerDFGToB3::compileValueBitRShift): 20 (JSC::FTL::DFG::LowerDFGToB3::compileToNumeric): 21 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 22 (JSC::FTL::DFG::LowerDFGToB3::compileIsBigInt): 23 (JSC::FTL::DFG::LowerDFGToB3::boolify): 24 (JSC::FTL::DFG::LowerDFGToB3::buildTypeOf): 25 (JSC::FTL::DFG::LowerDFGToB3::lowBigInt32): 26 (JSC::FTL::DFG::LowerDFGToB3::isBigInt32KnownNotCell): 27 (JSC::FTL::DFG::LowerDFGToB3::isBigInt32KnownNotNumber): 28 (JSC::FTL::DFG::LowerDFGToB3::isNotBigInt32KnownNotNumber): 29 (JSC::FTL::DFG::LowerDFGToB3::isNotAnyBigIntKnownNotNumber): 30 (JSC::FTL::DFG::LowerDFGToB3::isNotHeapBigIntUnknownWhetherCell): 31 (JSC::FTL::DFG::LowerDFGToB3::speculateBigInt32): 32 (JSC::FTL::DFG::LowerDFGToB3::speculateAnyBigInt): 33 (JSC::FTL::DFG::LowerDFGToB3::isBigInt32): Deleted. 34 (JSC::FTL::DFG::LowerDFGToB3::isNotBigInt32): Deleted. 35 (JSC::FTL::DFG::LowerDFGToB3::isNotAnyBigInt): Deleted. 36 1 37 2020-04-21 Yusuke Suzuki <ysuzuki@apple.com> 2 38 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r260377 r260512 544 544 if (node->binaryUseKind() == BigInt32Use) { 545 545 #if USE(BIGINT32) 546 setTypeForNode(node, SpecBigInt32); 546 // FIXME: We should have inlined implementation that always returns BigInt32. 547 // https://bugs.webkit.org/show_bug.cgi?id=210847 548 setTypeForNode(node, SpecBigInt); 547 549 #else 548 550 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r260397 r260512 3417 3417 // Things are a bit tricky because a right-shift by a negative number is a left-shift for BigInts. 3418 3418 // So even a right shift can overflow. 3419 // https://bugs.webkit.org/show_bug.cgi?id=210847 3419 3420 3420 3421 LValue left = lowJSValue(m_node->child1(), ManualOperandSpeculation); … … 7552 7553 LBasicBlock lastNext = m_out.appendTo(notNumber, continuation); 7553 7554 #if USE(BIGINT32) 7554 m_out.branch(isBigInt32 (value, provenType(m_node->child1())), unsure(continuation), unsure(notBigInt32));7555 m_out.branch(isBigInt32KnownNotNumber(value, provenType(m_node->child1())), unsure(continuation), unsure(notBigInt32)); 7555 7556 m_out.appendTo(notBigInt32); 7556 7557 #endif … … 8717 8718 LBasicBlock continuation = m_out.newBlock(); 8718 8719 8720 FTL_TYPE_CHECK(jsValueValue(left), m_node->child1(), ~SpecFullNumber, isNumber(left)); 8721 FTL_TYPE_CHECK(jsValueValue(right), m_node->child2(), ~SpecFullNumber, isNumber(right)); 8722 8719 8723 // Inserts a check that a value is a HeapBigInt, assuming only that we know it is not a BigInt32 8720 8724 auto checkIsHeapBigInt = [&](LValue lowValue, Edge highValue) { 8721 8725 if (m_interpreter.needsTypeCheck(highValue, SpecHeapBigInt)) { 8722 8726 ASSERT(mayHaveTypeCheck(highValue.useKind())); 8723 LValue checkFailed = isNotHeapBigIntUnknownWhetherCell(lowValue, ~SpecBigInt32);8727 LValue checkFailed = isNotHeapBigIntUnknownWhetherCell(lowValue, provenType(highValue) & ~SpecBigInt32); 8724 8728 appendOSRExit(BadType, jsValueValue(lowValue), highValue.node(), checkFailed, m_origin); 8725 8729 } 8726 8730 }; 8727 8731 8728 m_out.branch(isBigInt32 (left, provenType(m_node->child1())), unsure(leftIsBigInt32), unsure(leftIsNotBigInt32));8732 m_out.branch(isBigInt32KnownNotNumber(left, provenType(m_node->child1())), unsure(leftIsBigInt32), unsure(leftIsNotBigInt32)); 8729 8733 8730 8734 LBasicBlock lastNext = m_out.appendTo(leftIsBigInt32, bothAreBigInt32); 8731 m_out.branch(isBigInt32 (right, provenType(m_node->child2())), unsure(bothAreBigInt32), unsure(onlyLeftIsBigInt32));8735 m_out.branch(isBigInt32KnownNotNumber(right, provenType(m_node->child2())), unsure(bothAreBigInt32), unsure(onlyLeftIsBigInt32)); 8732 8736 8733 8737 m_out.appendTo(bothAreBigInt32, onlyLeftIsBigInt32); … … 8750 8754 8751 8755 m_out.appendTo(leftIsHeapBigInt, rightIsBigInt32); 8752 m_out.branch(isBigInt32 (right, provenType(m_node->child2())), unsure(rightIsBigInt32), unsure(rightIsNotBigInt32));8756 m_out.branch(isBigInt32KnownNotNumber(right, provenType(m_node->child2())), unsure(rightIsBigInt32), unsure(rightIsNotBigInt32)); 8753 8757 8754 8758 m_out.appendTo(rightIsBigInt32, rightIsNotBigInt32); … … 10923 10927 LBasicBlock lastNext = m_out.appendTo(isNotCellCase, isCellCase); 10924 10928 // FIXME: we should filter the provenType to include the fact that we know we are not dealing with a cell 10925 ValueFromBlock notCellResult = m_out.anchor(isBigInt32 (value, provenType(m_node->child1())));10929 ValueFromBlock notCellResult = m_out.anchor(isBigInt32KnownNotCell(value, provenType(m_node->child1()))); 10926 10930 m_out.jump(continuation); 10927 10931 … … 15466 15470 m_out.appendTo(notDoubleCase, bigInt32Case); 15467 15471 m_out.branch( 15468 isBigInt32 (value, provenType(edge) & ~SpecCell),15472 isBigInt32KnownNotNumber(value, provenType(edge) & ~SpecCell), 15469 15473 unsure(bigInt32Case), unsure(notBigInt32Case)); 15470 15474 … … 16192 16196 #if USE(BIGINT32) 16193 16197 m_out.appendTo(notNumberCase, notBigInt32Case); 16194 m_out.branch(isBigInt32 (value, provenType(child) & ~SpecCell), unsure(bigIntCase), unsure(notBigInt32Case));16198 m_out.branch(isBigInt32KnownNotNumber(value, provenType(child) & ~SpecCell), unsure(bigIntCase), unsure(notBigInt32Case)); 16195 16199 16196 16200 m_out.appendTo(notBigInt32Case, notNullCase); … … 16912 16916 if (isValid(value)) { 16913 16917 LValue result = value.value(); 16914 FTL_TYPE_CHECK(jsValueValue(result), edge, SpecBigInt32, isNotBigInt32(result)); 16918 FTL_TYPE_CHECK(jsValueValue(result), edge, ~SpecFullNumber, isNumber(result)); 16919 FTL_TYPE_CHECK(jsValueValue(result), edge, SpecBigInt32, isNotBigInt32KnownNotNumber(result)); 16915 16920 return result; 16916 16921 } … … 17109 17114 17110 17115 #if USE(BIGINT32) 17111 LValue isBigInt32 (LValue jsValue, SpeculatedType type = SpecFullTop)17116 LValue isBigInt32KnownNotCell(LValue jsValue, SpeculatedType type = SpecFullTop) 17112 17117 { 17113 17118 if (LValue proven = isProvenValue(type, SpecBigInt32)) 17114 17119 return proven; 17115 return m_out.equal( 17116 m_out.bitAnd(jsValue, m_out.constInt64(JSValue::BigInt32Mask)), 17117 m_out.constInt64(JSValue::BigInt32Tag)); 17118 } 17119 LValue isNotBigInt32(LValue jsValue, SpeculatedType type = SpecFullTop) 17120 return m_out.equal(m_out.bitAnd(jsValue, m_out.constInt64(JSValue::BigInt32Mask)), m_out.constInt64(JSValue::BigInt32Tag)); 17121 } 17122 LValue isBigInt32KnownNotNumber(LValue jsValue, SpeculatedType type = SpecFullTop) 17123 { 17124 if (LValue proven = isProvenValue(type, SpecBigInt32)) 17125 return proven; 17126 return m_out.equal(m_out.bitAnd(jsValue, m_out.constInt64(JSValue::BigInt32Tag)), m_out.constInt64(JSValue::BigInt32Tag)); 17127 } 17128 LValue isNotBigInt32KnownNotNumber(LValue jsValue, SpeculatedType type = SpecFullTop) 17120 17129 { 17121 17130 if (LValue proven = isProvenValue(type, ~SpecBigInt32)) 17122 17131 return proven; 17123 return m_out.notEqual( 17124 m_out.bitAnd(jsValue, m_out.constInt64(JSValue::BigInt32Mask)), 17125 m_out.constInt64(JSValue::BigInt32Tag)); 17132 return m_out.notEqual(m_out.bitAnd(jsValue, m_out.constInt64(JSValue::BigInt32Tag)), m_out.constInt64(JSValue::BigInt32Tag)); 17126 17133 } 17127 17134 LValue unboxBigInt32(LValue jsValue) … … 17135 17142 m_out.constInt64(JSValue::BigInt32Tag)); 17136 17143 } 17137 LValue isNotAnyBigInt (LValue jsValue, SpeculatedType type = SpecFullTop)17144 LValue isNotAnyBigIntKnownNotNumber(LValue jsValue, SpeculatedType type = SpecFullTop) 17138 17145 { 17139 17146 if (LValue proven = isProvenValue(type, ~SpecBigInt)) … … 17151 17158 LBasicBlock continuation = m_out.newBlock(); 17152 17159 17153 m_out.branch(isBigInt32 (jsValue, type), unsure(isBigInt32Case), unsure(isNotBigInt32Case));17160 m_out.branch(isBigInt32KnownNotNumber(jsValue, type), unsure(isBigInt32Case), unsure(isNotBigInt32Case)); 17154 17161 17155 17162 LBasicBlock lastNext = m_out.appendTo(isBigInt32Case, isNotBigInt32Case); … … 17688 17695 LBasicBlock continuation = m_out.newBlock(); 17689 17696 17690 ValueFromBlock defaultTo False = m_out.anchor(m_out.booleanFalse);17697 ValueFromBlock defaultToTrue = m_out.anchor(m_out.booleanTrue); 17691 17698 m_out.branch(isCell(value, type), unsure(isCellCase), unsure(continuation)); 17692 17699 17693 17700 LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation); 17694 ValueFromBlock returnForCell = m_out.anchor(is HeapBigInt(value, type));17701 ValueFromBlock returnForCell = m_out.anchor(isNotHeapBigInt(value, type)); 17695 17702 m_out.jump(continuation); 17696 17703 17697 17704 m_out.appendTo(continuation, lastNext); 17698 LValue result = m_out.phi(Int32, defaultTo False, returnForCell);17705 LValue result = m_out.phi(Int32, defaultToTrue, returnForCell); 17699 17706 return result; 17700 17707 } … … 18182 18189 { 18183 18190 LValue value = lowJSValue(edge, ManualOperandSpeculation); 18184 FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBigInt32, isNotBigInt32(value)); 18191 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecFullNumber, isNumber(value)); 18192 FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBigInt32, isNotBigInt32KnownNotNumber(value)); 18185 18193 } 18186 18194 … … 18188 18196 { 18189 18197 LValue value = lowJSValue(edge, ManualOperandSpeculation); 18190 FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBigInt, isNotAnyBigInt(value)); 18198 FTL_TYPE_CHECK(jsValueValue(value), edge, ~SpecFullNumber, isNumber(value)); 18199 FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBigInt, isNotAnyBigIntKnownNotNumber(value)); 18191 18200 } 18192 18201 #endif
Note: See TracChangeset
for help on using the changeset viewer.