Skip to content

Specialization for longs should check for compactness #138302

@Fidget-Spinner

Description

@Fidget-Spinner

Bug report

Bug description:

As part of #135479, I made the specializing interpreter only specialize compact longs.

I forgot to check for the long's compactness in the specializer. The downside is that there's a bit of perf lost when adding large ints now due to repeated failed specialization and deopt.

For example for the following code:

def foo():
    for _ in range(100000000):
        y = 1000000000000000000000000000000000
        y + y

foo()

y + y specializes to _BINARY_OP_ADD_INT, when it should be _BINARY_OP/_BINARY_OP_EXTEND

The fix is simple:
Change this line
https://github.com/python/cpython/blob/main/Python/specialize.c#L2598
from

            if (PyLong_CheckExact(lhs)) {
                specialize(instr, BINARY_OP_ADD_INT);
                return;
            }

to

            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
                specialize(instr, BINARY_OP_ADD_INT);
                return;
            }

Then, add a test in Lib/test/test_opcache.py, checking for _BINARY_OP/_BINARY_OP_EXTEND.

CPython versions tested on:

CPython main branch, 3.15, 3.14

Operating systems tested on:

No response

Linked PRs

Metadata

Metadata

Assignees

Labels

3.15new features, bugs and security fixeseasyinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions