https://github.com/python/cpython/commit/66eafc9ea74e5233f2c46b424729d6dadfbb3111
commit: 66eafc9ea74e5233f2c46b424729d6dadfbb3111
branch: main
author: Hai Zhu <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-03-10T12:12:48+08:00
summary:

gh-144681: Fix JIT trace builder assertion failure when conditional branch jump 
target coincides with fallthrough target (GH-144742)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst
M Lib/test/test_capi/test_opt.py
M Python/optimizer.c

diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 90e2ed20d1f6b3..8fa4f02afb5b45 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -461,6 +461,19 @@ def testfunc(n):
         uops = get_opnames(ex)
         self.assertIn(self.guard_is_false, uops)
 
+    def test_branch_coincident_targets(self):
+        # test for gh-144681: https://github.com/python/cpython/issues/144681
+        def testfunc(n):
+            for _ in range(n):
+                r = [x for x in range(10) if [].append(x) or True]
+            return r
+
+        res = testfunc(TIER2_THRESHOLD)
+        ex = get_first_executor(testfunc)
+
+        self.assertEqual(res, list(range(10)))
+        self.assertIsNotNone(ex)
+
     def test_for_iter_tier_two(self):
         class MyIter:
             def __init__(self, n):
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst
new file mode 100644
index 00000000000000..c8ca7a7fa194ee
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-12-12-39-50.gh-issue-144681.Ns2OT2.rst
@@ -0,0 +1 @@
+Fix a JIT assertion failure when a conditional branch jumps to the same target 
as the fallthrough path.
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 4387bcb0d67832..7315bb6b9f603d 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -786,8 +786,8 @@ _PyJit_translate_single_bytecode_to_trace(
             _Py_CODEUNIT *computed_next_instr = 
computed_next_instr_without_modifiers + 
(computed_next_instr_without_modifiers->op.code == NOT_TAKEN);
             _Py_CODEUNIT *computed_jump_instr = 
computed_next_instr_without_modifiers + oparg;
             assert(next_instr == computed_next_instr || next_instr == 
computed_jump_instr);
-            int jump_happened = computed_jump_instr == next_instr;
-            assert(jump_happened == (target_instr[1].cache & 1));
+            int jump_happened = target_instr[1].cache & 1;
+            assert(jump_happened ? (next_instr == computed_jump_instr) : 
(next_instr == computed_next_instr));
             uint32_t uopcode = BRANCH_TO_GUARD[opcode - 
POP_JUMP_IF_FALSE][jump_happened];
             ADD_TO_TRACE(uopcode, 0, 0, INSTR_IP(jump_happened ? 
computed_next_instr : computed_jump_instr, old_code));
             break;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to