Package: release.debian.org Severity: normal Tags: bookworm User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: py...@packages.debian.org Control: affects -1 + src:pypy3
[ Reason ] A user ran into a JIT bug in pypy3 in bookworm that has been resolved upstream. It's a simple bug and trivial to backport the fix for. [ Impact ] More users may run into this particular JIT bug. [ Tests ] The bug comes with a regression test, that passes. [ Risks ] The change is very simple. The patch applied cleanly and that code hasn't been modified upstream, since this patch. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] An assert that crashes the interpreter is replaced by an exception that will drop back out of the JIT.
diff -Nru pypy3-7.3.11+dfsg/debian/changelog pypy3-7.3.11+dfsg/debian/changelog --- pypy3-7.3.11+dfsg/debian/changelog 2023-02-06 10:12:43.000000000 -0400 +++ pypy3-7.3.11+dfsg/debian/changelog 2024-02-01 20:41:13.000000000 -0400 @@ -1,3 +1,10 @@ +pypy3 (7.3.11+dfsg-2+deb12u1) bookworm; urgency=medium + + * Avoid an rpython assertion error in the JIT if integer ranges don't + overlap in a loop. (Closes: #1062460) + + -- Stefano Rivera <stefa...@debian.org> Thu, 01 Feb 2024 20:41:13 -0400 + pypy3 (7.3.11+dfsg-2) unstable; urgency=medium * Mark pypy3 as being EXTERNALLY-MANAGED. diff -Nru pypy3-7.3.11+dfsg/debian/patches/int-jit-assert.patch pypy3-7.3.11+dfsg/debian/patches/int-jit-assert.patch --- pypy3-7.3.11+dfsg/debian/patches/int-jit-assert.patch 1969-12-31 20:00:00.000000000 -0400 +++ pypy3-7.3.11+dfsg/debian/patches/int-jit-assert.patch 2024-02-01 20:41:13.000000000 -0400 @@ -0,0 +1,100 @@ +From: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> +Date: Fri, 3 Mar 2023 14:15:42 +0100 +Subject: Upstream: #3892: fix wrong assert in intutils, + it should be an InvalidLoop instead + +I introduced the assert in 5909f5e0a75c. before that, inconsistent intersects +would just do nothing, which I am not sure is a better solution than raising +InvalidLoop + +Bug-Debian: https://bugs.debian.org/1062460 +Origin: upstream, https://github.com/pypy/pypy/commit/ba8a3c45b9afe068c06780b4c34709c852ae20ea +--- + rpython/jit/metainterp/optimizeopt/intutils.py | 8 +++++- + .../metainterp/optimizeopt/test/test_intbound.py | 5 ++-- + rpython/jit/metainterp/test/test_ajit.py | 33 ++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 4 deletions(-) + +diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py b/rpython/jit/metainterp/optimizeopt/intutils.py +index 381d0a2..e9ba7f7 100644 +--- a/rpython/jit/metainterp/optimizeopt/intutils.py ++++ b/rpython/jit/metainterp/optimizeopt/intutils.py +@@ -129,7 +129,13 @@ class IntBound(AbstractInfo): + return 0 <= self.lower + + def intersect(self, other): +- assert not self.known_gt(other) and not self.known_lt(other) ++ from rpython.jit.metainterp.optimize import InvalidLoop ++ if self.known_gt(other) or self.known_lt(other): ++ # they don't overlap, which makes the loop invalid ++ # this never happens in regular linear traces, but it can happen in ++ # combination with unrolling/loop peeling ++ raise InvalidLoop("two integer ranges don't overlap") ++ + r = False + if self.make_ge_const(other.lower): + r = True +diff --git a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py +index d4a0db4..ea9b74c 100644 +--- a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py ++++ b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py +@@ -225,13 +225,12 @@ def test_intersect(): + assert not b.contains(n) + + def test_intersect_bug(): ++ from rpython.jit.metainterp.optimize import InvalidLoop + b1 = bound(17, 17) + b2 = bound(1, 1) +- with pytest.raises(AssertionError): ++ with pytest.raises(InvalidLoop): + b1.intersect(b2) + +- +- + def test_add_bound(): + for _, _, b1 in some_bounds(): + for _, _, b2 in some_bounds(): +diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py +index 29a8bf8..68e7d60 100644 +--- a/rpython/jit/metainterp/test/test_ajit.py ++++ b/rpython/jit/metainterp/test/test_ajit.py +@@ -3256,6 +3256,39 @@ class BasicTests: + res = self.interp_operations(f, [127 - 256 * 29]) + assert res == 127 + ++ def test_bug_inline_short_preamble_can_be_inconsistent_in_optimizeopt(self): ++ myjitdriver = JitDriver(greens = [], reds = "auto") ++ class Str(object): ++ _immutable_fields_ = ['s'] ++ def __init__(self, s): ++ self.s = s ++ ++ empty = Str("") ++ space = Str(" ") ++ ++ def f(a, b): ++ line = " " * a + " a" * b ++ token = "" ++ res = [] ++ index = 0 ++ while True: ++ myjitdriver.jit_merge_point() ++ if index >= len(line): ++ break ++ char = line[index] ++ index += 1 ++ if char == space.s: ++ if token != empty.s: ++ res.append(token) ++ token = empty.s ++ else: ++ token += char ++ return len(res) ++ args = [50, 50] ++ res = self.meta_interp(f, args) ++ assert res == f(*args) ++ ++ + class BaseLLtypeTests(BasicTests): + + def test_identityhash(self): diff -Nru pypy3-7.3.11+dfsg/debian/patches/series pypy3-7.3.11+dfsg/debian/patches/series --- pypy3-7.3.11+dfsg/debian/patches/series 2023-02-06 10:12:43.000000000 -0400 +++ pypy3-7.3.11+dfsg/debian/patches/series 2024-02-01 20:41:13.000000000 -0400 @@ -19,3 +19,4 @@ noise python3-sphinx setuptools-59-editable-installs +int-jit-assert.patch