https://github.com/python/cpython/commit/e02ac1d907d7cf32db5592593bd0c19a88cc6131
commit: e02ac1d907d7cf32db5592593bd0c19a88cc6131
branch: main
author: Neko Asakura <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-14T12:51:05+08:00
summary:

gh-148515: make `optimizer_generator` respect multiple caches (#148524)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-04-13-16-52-33.gh-issue-148515.09xulC.rst
M Lib/test/test_generated_cases.py
M Python/optimizer_cases.c.h
M Tools/cases_generator/optimizer_generator.py

diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index bb831fa984c34b..33fae682a3ceec 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -2696,5 +2696,30 @@ def test_replace_opocode_uop_reject_array_effects(self):
                                     "Pure evaluation cannot take array-like 
inputs"):
             self.run_cases_test(input, input2, output)
 
+    def test_overridden_abstract_with_multiple_caches(self):
+        input = """
+        op(OP, (version/1, unused/1, index/1, value -- res)) {
+            res = SPAM(version, index, value);
+        }
+        """
+        input2 = """
+        op(OP, (value -- res)) {
+            res = eggs(version, index, value);
+        }
+        """
+        output = """
+        case OP: {
+            JitOptRef value;
+            JitOptRef res;
+            value = stack_pointer[-1];
+            uint16_t version = (uint16_t)this_instr->operand0;
+            uint16_t index = (uint16_t)this_instr->operand1;
+            res = eggs(version, index, value);
+            stack_pointer[-1] = res;
+            break;
+        }
+        """
+        self.run_cases_test(input, input2, output)
+
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-13-16-52-33.gh-issue-148515.09xulC.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-13-16-52-33.gh-issue-148515.09xulC.rst
new file mode 100644
index 00000000000000..53d91c8198f3d0
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-13-16-52-33.gh-issue-148515.09xulC.rst
@@ -0,0 +1,2 @@
+Fix a bug in the JIT optimizer reading operands for uops with multiple
+caches.
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index deb92f5d9ab0f1..2547c959ed50ae 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -2072,7 +2072,7 @@
         case _LOAD_GLOBAL_MODULE: {
             JitOptRef res;
             uint16_t version = (uint16_t)this_instr->operand0;
-            uint16_t index = (uint16_t)this_instr->operand0;
+            uint16_t index = (uint16_t)this_instr->operand1;
             (void)index;
             PyObject *cnst = NULL;
             if (ctx->frame->func != NULL) {
@@ -2119,7 +2119,7 @@
         case _LOAD_GLOBAL_BUILTINS: {
             JitOptRef res;
             uint16_t version = (uint16_t)this_instr->operand0;
-            uint16_t index = (uint16_t)this_instr->operand0;
+            uint16_t index = (uint16_t)this_instr->operand1;
             (void)version;
             (void)index;
             PyObject *cnst = NULL;
@@ -2487,7 +2487,7 @@
             JitOptRef o;
             owner = stack_pointer[-1];
             uint32_t dict_version = (uint32_t)this_instr->operand0;
-            uint16_t index = (uint16_t)this_instr->operand0;
+            uint16_t index = (uint16_t)this_instr->operand1;
             (void)dict_version;
             (void)index;
             attr = PyJitRef_NULL;
diff --git a/Tools/cases_generator/optimizer_generator.py 
b/Tools/cases_generator/optimizer_generator.py
index b6b59838a70501..784e1a8a2d1f9b 100644
--- a/Tools/cases_generator/optimizer_generator.py
+++ b/Tools/cases_generator/optimizer_generator.py
@@ -412,6 +412,7 @@ def write_uop(
                     args.append(input.name)
             out.emit(f'DEBUG_PRINTF({", ".join(args)});\n')
         if override:
+            idx = 0
             for cache in uop.caches:
                 if cache.name != "unused":
                     if cache.size == 4:
@@ -419,7 +420,8 @@ def write_uop(
                     else:
                         type = f"uint{cache.size*16}_t "
                         cast = f"uint{cache.size*16}_t"
-                    out.emit(f"{type}{cache.name} = 
({cast})this_instr->operand0;\n")
+                    out.emit(f"{type}{cache.name} = 
({cast})this_instr->operand{idx};\n")
+                    idx += 1
         if override:
             emitter = OptimizerEmitter(out, {}, uop, stack.copy())
             # No reference management of inputs needed.

_______________________________________________
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