]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-130415: Narrow int to 0 based on boolean tests (GH-130772)
authorKlaus117 <keenanlau12@gmail.com>
Tue, 4 Mar 2025 20:44:09 +0000 (12:44 -0800)
committerGitHub <noreply@github.com>
Tue, 4 Mar 2025 20:44:09 +0000 (12:44 -0800)
Lib/test/test_capi/test_opt.py
Misc/ACKS
Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-01-21-04.gh-issue-130415.ibOV6B.rst [new file with mode: 0644]
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h
Python/optimizer_symbols.c

index b7083dbfb89db8f2ba8e0c8e24fffba81e11f69a..a4faab2124b9c704bc829e086b6753ba3b6e0a80 100644 (file)
@@ -1499,6 +1499,37 @@ class TestUopsOptimization(unittest.TestCase):
         # But all of the appends we care about are still there:
         self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
 
+    def test_narrow_type_to_constant_int_zero(self):
+        def f(n):
+            trace = []
+            for i in range(n):
+                # zero is always (int) 0, but we can only prove that it's a integer:
+                false = i == TIER2_THRESHOLD # this will always be false, while hopefully still fooling optimizer improvements
+                zero = false + 0 # this should always set the variable zero equal to 0
+                trace.append("A")
+                if not zero:  # Kept.
+                    trace.append("B")
+                    if not zero:  # Removed!
+                        trace.append("C")
+                    trace.append("D")
+                    if zero:  # Removed!
+                        trace.append("X")
+                    trace.append("E")
+                trace.append("F")
+                if zero:  # Removed!
+                    trace.append("X")
+                trace.append("G")
+            return trace
+
+        trace, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
+        self.assertEqual(trace, list("ABCDEFG") * TIER2_THRESHOLD)
+        self.assertIsNotNone(ex)
+        uops = get_opnames(ex)
+        # Only one guard remains:
+        self.assertEqual(uops.count("_GUARD_IS_FALSE_POP"), 1)
+        self.assertEqual(uops.count("_GUARD_IS_TRUE_POP"), 0)
+        # But all of the appends we care about are still there:
+        self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
 
 def global_identity(x):
     return x
index 7bf1d9c99ea24cd45bdcb7e86806fb3f8e76e440..2526e78389dea213bec3724a79f6d4b38f99440a 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1061,6 +1061,7 @@ Detlef Lannert
 RĂ©mi Lapeyre
 Soren Larsen
 Amos Latteier
+Keenan Lau
 Piers Lauder
 Ben Laurie
 Yoni Lavi
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-01-21-04.gh-issue-130415.ibOV6B.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-01-21-04.gh-issue-130415.ibOV6B.rst
new file mode 100644 (file)
index 0000000..636b221
--- /dev/null
@@ -0,0 +1 @@
+Improve JIT understanding of integers in boolean context.
index c4e4b28e50d211441015ba2b4a4d0242715d61a1..2aeed24a8c6c3249f542d257002bbc9f7e41010c 100644 (file)
@@ -406,7 +406,7 @@ dummy_func(void) {
     op(_TO_BOOL_INT, (value -- res)) {
         if (!optimize_to_bool(this_instr, ctx, value, &res)) {
             sym_set_type(value, &PyLong_Type);
-            res = sym_new_type(ctx, &PyBool_Type);
+            res = sym_new_truthiness(ctx, value, true);
         }
     }
 
index 397184dd87ad7d45a9100e30d45de969edcfdc8e..9555e141ed5c9febd42f499706f3de859b887265 100644 (file)
             value = stack_pointer[-1];
             if (!optimize_to_bool(this_instr, ctx, value, &res)) {
                 sym_set_type(value, &PyLong_Type);
-                res = sym_new_type(ctx, &PyBool_Type);
+                res = sym_new_truthiness(ctx, value, true);
             }
             stack_pointer[-1] = res;
             break;
index e8a3b918e56a9456ea9f94f9c068f30d14a752d1..28a2791f5e7de67d2d9f86045c14d851f9aa9279 100644 (file)
@@ -299,6 +299,9 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val
             else if (type == &PyBool_Type) {
                 _Py_uop_sym_set_const(ctx, value, Py_False);
             }
+            else if (type == &PyLong_Type) {
+                _Py_uop_sym_set_const(ctx, value, Py_GetConstant(Py_CONSTANT_ZERO));
+            }
             // TODO: More types (GH-130415)!
             make_const(sym, const_val);
             return;