]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138302: Specialize int ops only if ints are compact (GH-138347)
authorTapeline <mail@tapeline.dev>
Mon, 1 Sep 2025 17:33:15 +0000 (22:33 +0500)
committerGitHub <noreply@github.com>
Mon, 1 Sep 2025 17:33:15 +0000 (01:33 +0800)
Lib/test/test_opcache.py
Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-21-52-54.gh-issue-138302.-ez47B.rst [new file with mode: 0644]
Python/specialize.c

index 30baa09048616ce743cae9aeb84926370f649b97..f1271fc540ebd8bdce836e04590690d13ebf779c 100644 (file)
@@ -1333,6 +1333,21 @@ class TestSpecializer(TestBase):
         self.assert_specialized(binary_op_add_int, "BINARY_OP_ADD_INT")
         self.assert_no_opcode(binary_op_add_int, "BINARY_OP")
 
+        def binary_op_int_non_compact():
+            for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
+                a, b = 10000000000, 1
+                c = a + b
+                self.assertEqual(c, 10000000001)
+                c = a - b
+                self.assertEqual(c, 9999999999)
+                c = a * b
+                self.assertEqual(c, 10000000000)
+
+        binary_op_int_non_compact()
+        self.assert_no_opcode(binary_op_int_non_compact, "BINARY_OP_ADD_INT")
+        self.assert_no_opcode(binary_op_int_non_compact, "BINARY_OP_SUBTRACT_INT")
+        self.assert_no_opcode(binary_op_int_non_compact, "BINARY_OP_MULTIPLY_INT")
+
         def binary_op_add_unicode():
             for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
                 a, b = "foo", "bar"
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-21-52-54.gh-issue-138302.-ez47B.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-21-52-54.gh-issue-138302.-ez47B.rst
new file mode 100644 (file)
index 0000000..156b9df
--- /dev/null
@@ -0,0 +1,3 @@
+``BINARY_OP`` now specializes to ``BINARY_OP_ADD_INT``,
+``BINARY_OP_SUBTRACT_INT`` or ``BINARY_OP_MULTIPLY_INT`` if operands
+are compact ints.
index 38df5741f32520950ad492b7fb277e511e603367..47f7b27b4908fd792a90114cfefd9171b2bc0df8 100644 (file)
@@ -2595,7 +2595,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
                 specialize(instr, BINARY_OP_ADD_UNICODE);
                 return;
             }
-            if (PyLong_CheckExact(lhs)) {
+            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
                 specialize(instr, BINARY_OP_ADD_INT);
                 return;
             }
@@ -2609,7 +2609,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
             if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
                 break;
             }
-            if (PyLong_CheckExact(lhs)) {
+            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
                 specialize(instr, BINARY_OP_MULTIPLY_INT);
                 return;
             }
@@ -2623,7 +2623,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
             if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
                 break;
             }
-            if (PyLong_CheckExact(lhs)) {
+            if (_PyLong_CheckExactAndCompact(lhs) && _PyLong_CheckExactAndCompact(rhs)) {
                 specialize(instr, BINARY_OP_SUBTRACT_INT);
                 return;
             }