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

This commit is contained in:
Neko Asakura 2026-04-14 00:51:05 -04:00 committed by GitHub
parent c40e8b016a
commit e02ac1d907
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 33 additions and 4 deletions

View file

@ -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()

View file

@ -0,0 +1,2 @@
Fix a bug in the JIT optimizer reading operands for uops with multiple
caches.

View file

@ -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;

View 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.