From: Neko Asakura Date: Tue, 14 Apr 2026 04:51:05 +0000 (-0400) Subject: gh-148515: make `optimizer_generator` respect multiple caches (#148524) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e02ac1d907d7cf32db5592593bd0c19a88cc6131;p=thirdparty%2FPython%2Fcpython.git gh-148515: make `optimizer_generator` respect multiple caches (#148524) --- diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index bb831fa984c3..33fae682a3ce 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -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 index 000000000000..53d91c8198f3 --- /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 deb92f5d9ab0..2547c959ed50 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 b6b59838a705..784e1a8a2d1f 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.