]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-148515: make `optimizer_generator` respect multiple caches (#148524)
authorNeko Asakura <neko.asakura@outlook.com>
Tue, 14 Apr 2026 04:51:05 +0000 (00:51 -0400)
committerGitHub <noreply@github.com>
Tue, 14 Apr 2026 04:51:05 +0000 (12:51 +0800)
Lib/test/test_generated_cases.py
Misc/NEWS.d/next/Core_and_Builtins/2026-04-13-16-52-33.gh-issue-148515.09xulC.rst [new file with mode: 0644]
Python/optimizer_cases.c.h
Tools/cases_generator/optimizer_generator.py

index bb831fa984c34bde476ae0b624b12ac8651b7b2a..33fae682a3ceec7eb82b57da80931d8e1717856a 100644 (file)
@@ -2696,5 +2696,30 @@ class TestGeneratedAbstractCases(unittest.TestCase):
                                     "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 (file)
index 0000000..53d91c8
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a bug in the JIT optimizer reading operands for uops with multiple
+caches.
index deb92f5d9ab0f1604ff3f971de76c61163369161..2547c959ed50ae447f8fdc10f622020dc97bf20e 100644 (file)
         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) {
         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;
             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;
index b6b59838a70501984c0c8149df439da82d750f2a..784e1a8a2d1f9b697b861a2305d8b2ca5aa118b5 100644 (file)
@@ -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.