From 103e56eb63e7bd290bb1aeea6c714bd3d13dd89d Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Fri, 15 Dec 2023 23:35:00 -0800 Subject: [PATCH] DFG might force a local to be double even if we store non-numeric values into it https://bugs.webkit.org/show_bug.cgi?id=263090 Reviewed by Keith Miller. This changes fixes tallyVotesForShouldUseDoubleFormat() to set NotUsingDoubleFormat if the variable is no longer predicted to hold only doubles. * JSTests/stress/double-inlined-call-argument.js: Added. * JSTests/stress/regress-116397731.js: Added. * Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp: (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat): Originally-landed-as: 267815.352@safari-7617-branch (11987a2c00bf). rdar://119597752 Canonical link: https://commits.webkit.org/272168@main --- .../stress/double-inlined-call-argument.js | 22 +++++++++++++++++++ JSTests/stress/regress-116397731.js | 16 ++++++++++++++ .../dfg/DFGVariableAccessData.cpp | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 JSTests/stress/double-inlined-call-argument.js create mode 100644 JSTests/stress/regress-116397731.js diff --git a/JSTests/stress/double-inlined-call-argument.js b/JSTests/stress/double-inlined-call-argument.js new file mode 100644 index 0000000000000..d27dce971a0d9 --- /dev/null +++ b/JSTests/stress/double-inlined-call-argument.js @@ -0,0 +1,22 @@ +function foo(a, b, c, p) { + a = b + c; + if (p) { + a++; + return a; + } +} + +function bar(a, b) { + return foo("hello", a, b, a <= b); +} + +noInline(bar); + +for (var i = 0; i < 100000; ++i) { + var result = bar(2000000000, 2000000000.5); + if (result != 4000000001.5) + throw new Error(`Bad result: ${result}!`); +} + +if (reoptimizationRetryCount(bar) != 0) + throw new Error(`Should not have reoptimized bar, but reoptimized ${reoptimizationRetryCount(bar)} times.`); diff --git a/JSTests/stress/regress-116397731.js b/JSTests/stress/regress-116397731.js new file mode 100644 index 0000000000000..fe9db950f4c53 --- /dev/null +++ b/JSTests/stress/regress-116397731.js @@ -0,0 +1,16 @@ +var out; + +function func0(value) { + if (value) {} + out = value; + value = value + 1 + 2; +} + +function main() { + for (let i = 0; i < 0x100000; i++) + func0(undefined); + if (out !== undefined) + throw new Error(`Bad value: ${out}!`); +} + +main(); diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp b/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp index 2ac2ee39b4cca..1cb933ba841bf 100644 --- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp +++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.cpp @@ -131,7 +131,7 @@ bool VariableAccessData::tallyVotesForShouldUseDoubleFormat() if (!newValueOfShouldUseDoubleFormat) { // We monotonically convert to double. Hence, if the fixpoint leads us to conclude that we should // switch back to int, we instead ignore this and stick with double. - return false; + return DFG::mergeDoubleFormatState(m_doubleFormatState, NotUsingDoubleFormat); } if (m_doubleFormatState == UsingDoubleFormat)