Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • pypy pypy
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 673
    • Issues 673
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 13
    • Merge requests 13
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • PyPy
  • pypypypy
  • Issues
  • #3832
Closed
Open
Created Oct 14, 2022 by Carl Friedrich Bolz-Tereick@cfbolzOwner

Wrong optimization bug around bounds analysis of int_add

Nico Rittinghaus, my bachelor student and I found the following existing JIT test today, which passes, but is actually incorrect (see comments):

    def test_bound_lt_add_before(self):
        # removing the second guard is incorrect.
        ops = """
        [i0]                    # MAXINT-9
        i2 = int_add(i0, 10)    # == MININT (overflow)
        i3 = int_lt(i2, 15)     # == TRUE
        guard_true(i3) []
        i1 = int_lt(i0, 6)      # == FALSE
        guard_true(i1) []       # this guard can fail, must not be removed!
        jump(i0)
        """
        expected = """
        [i0]
        i2 = int_add(i0, 10)
        i3 = int_lt(i2, 15)
        guard_true(i3) []
        jump(i0)
        """
        self.optimize_loop(ops, expected)

Admittedly it's about int_add, which is quite rarely used in PyPy and its semantics is probably under-specified. However, if you use __pypy__.intop.int_add, you can still get programs that behave differently with and without the JIT:

cfbolz@drais:~/temp/miscompile$ cat x.py 
import __pypy__
import sys

def wrong(x): # does exactly the thing same as the test
    a = __pypy__.intop.int_add(x, 10)
    if a < 15:
        if x < 6:
            return 0
        return 1
    return 2

def main():
    res = 0
    for i in list(range(-100000, 0)) + [sys.maxsize]:
        res += wrong(i)
    print(res)
main() # prints 1 without JIT, 0 with JIT
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking