https://github.com/python/cpython/commit/6e081614eb7b7e93d3ddcdd1c34abe551e9c6550
commit: 6e081614eb7b7e93d3ddcdd1c34abe551e9c6550
branch: main
author: Kumar Aditya <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-08T23:23:20+08:00
summary:
gh-148210: fix incorrect `_BINARY_OP_SUBSCR_DICT` JIT optimization (GH-148213)
files:
M Lib/test/test_capi/test_opt.py
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index b25c3c4c4e70a6..f89f0d8bc4ee2a 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -2340,6 +2340,21 @@ def testfunc(n):
self.assertIn("_BINARY_OP_SUBSCR_DICT_KNOWN_HASH", uops)
self.assertNotIn("_BINARY_OP_SUBSCR_DICT", uops)
+
+ def test_binary_op_subscr_constant_frozendict_known_hash(self):
+ def testfunc(n):
+ x = 0
+ for _ in range(n):
+ x += FROZEN_DICT_CONST['x']
+ return x
+
+ res, ex = self._run_with_optimizer(testfunc, 2 * TIER2_THRESHOLD)
+ self.assertEqual(res, 2 * TIER2_THRESHOLD)
+ self.assertIsNotNone(ex)
+ uops = get_opnames(ex)
+ self.assertNotIn("_BINARY_OP_SUBSCR_DICT_KNOWN_HASH", uops)
+ self.assertNotIn("_BINARY_OP_SUBSCR_DICT", uops)
+
def test_store_subscr_dict_known_hash(self):
# str, int, bytes, float, complex, tuple and any python object which
has generic hash
def testfunc(n):
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index f0abdc098dd8f1..3ba404b81ea043 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -515,18 +515,18 @@ dummy_func(void) {
}
op(_BINARY_OP_SUBSCR_DICT, (dict_st, sub_st -- res, ds, ss)) {
- PyObject *sub = sym_get_const(ctx, sub_st);
- if (sub != NULL) {
- optimize_dict_known_hash(ctx, dependencies, this_instr,
- sub, _BINARY_OP_SUBSCR_DICT_KNOWN_HASH);
- }
res = sym_new_not_null(ctx);
ds = dict_st;
ss = sub_st;
+ PyObject *sub = sym_get_const(ctx, sub_st);
if (sym_is_not_container(sub_st) &&
sym_matches_type(dict_st, &PyFrozenDict_Type)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(dict_st, sub_st, res);
}
+ else if (sub != NULL) {
+ optimize_dict_known_hash(ctx, dependencies, this_instr,
+ sub, _BINARY_OP_SUBSCR_DICT_KNOWN_HASH);
+ }
}
op(_BINARY_OP_SUBSCR_LIST_SLICE, (list_st, sub_st -- res, ls, ss)) {
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 6f9b0e6a4d0373..2c8a0bff13ce35 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -1463,14 +1463,10 @@
JitOptRef ss;
sub_st = stack_pointer[-1];
dict_st = stack_pointer[-2];
- PyObject *sub = sym_get_const(ctx, sub_st);
- if (sub != NULL) {
- optimize_dict_known_hash(ctx, dependencies, this_instr,
- sub, _BINARY_OP_SUBSCR_DICT_KNOWN_HASH);
- }
res = sym_new_not_null(ctx);
ds = dict_st;
ss = sub_st;
+ PyObject *sub = sym_get_const(ctx, sub_st);
if (sym_is_not_container(sub_st) &&
sym_matches_type(dict_st, &PyFrozenDict_Type)) {
if (
@@ -1520,6 +1516,10 @@
break;
}
}
+ else if (sub != NULL) {
+ optimize_dict_known_hash(ctx, dependencies, this_instr,
+ sub, _BINARY_OP_SUBSCR_DICT_KNOWN_HASH);
+ }
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer[-1] = ds;
_______________________________________________
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]