https://github.com/python/cpython/commit/c989e74446836ce8a00ae002d4c229c81e1f7905
commit: c989e74446836ce8a00ae002d4c229c81e1f7905
branch: main
author: Klaus117 <keenanla...@gmail.com>
committer: brandtbucher <brandtbuc...@gmail.com>
date: 2025-03-04T12:44:09-08:00
summary:

GH-130415: Narrow int to 0 based on boolean tests (GH-130772)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-01-21-04.gh-issue-130415.ibOV6B.rst
M Lib/test/test_capi/test_opt.py
M Misc/ACKS
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
M Python/optimizer_symbols.c

diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index b7083dbfb89db8..a4faab2124b9c7 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -1499,6 +1499,37 @@ def f(n):
         # 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
diff --git a/Misc/ACKS b/Misc/ACKS
index 7bf1d9c99ea24c..2526e78389dea2 100644
--- 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
index 00000000000000..636b2211b724ec
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-03-01-21-04.gh-issue-130415.ibOV6B.rst
@@ -0,0 +1 @@
+Improve JIT understanding of integers in boolean context.
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index c4e4b28e50d211..2aeed24a8c6c32 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -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);
         }
     }
 
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 397184dd87ad7d..9555e141ed5c9f 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -178,7 +178,7 @@
             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;
diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c
index e8a3b918e56a94..28a2791f5e7de6 100644
--- a/Python/optimizer_symbols.c
+++ b/Python/optimizer_symbols.c
@@ -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;

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to