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]