Skip to content

Commit 27dd764

Browse files
committed
simplify: fix output type bug + add hir_output_type bridge
Root cause: simplify_env_emit was not setting output register types, causing 'new output type TTop isn't compatible with old output type' assertion failures. Fix: added hir_output_type C bridge (wraps C++ outputType) and integrated into simplify_env_emit. All emitted instructions now get correct output types automatically, mirroring C++ emitCInstr. Also reverted Float/Long/Bool comparison paths from Compare handler (need to re-verify with outputType bridge before re-adding). Added LoadVarObjectSize known-object path.
1 parent f4def10 commit 27dd764

File tree

5 files changed

+44
-33
lines changed

5 files changed

+44
-33
lines changed

Python/jit/hir/hir_c_api.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,10 @@ void hir_reg_uses_destroy(HirRegUses uses) {
466466

467467
/* ---- outputType with override ---- */
468468

469+
HirType hir_output_type(HirInstr instr) {
470+
return Type::toHirType(outputType(*as_instr(instr)));
471+
}
472+
469473
HirType hir_output_type_with_override(HirInstr instr,
470474
size_t override_idx,
471475
const HirType *override_type) {

Python/jit/hir/hir_c_api.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,10 @@ HirInstr hir_reg_uses_get(HirRegUses uses, HirRegister reg, size_t idx);
624624
/* Free the RegUses handle. */
625625
void hir_reg_uses_destroy(HirRegUses uses);
626626

627-
/* ---- outputType with override ---- */
627+
/* ---- outputType ---- */
628+
629+
/* Compute the output type of an instruction based on its opcode and operands. */
630+
HirType hir_output_type(HirInstr instr);
628631

629632
/* Compute the output type of an instruction, but override one operand's
630633
* type at override_idx with override_type. Used by guard removal to

Python/jit/hir/simplify.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2797,8 +2797,13 @@ Register* simplifyInstr(Env& env, const Instr* instr) {
27972797
case Opcode::kLoadArrayItem:
27982798
return simplifyLoadArrayItem(
27992799
env, static_cast<const LoadArrayItem*>(instr));
2800-
case Opcode::kLoadVarObjectSize:
2800+
case Opcode::kLoadVarObjectSize: {
2801+
SimplifyEnv cenv = make_c_env();
2802+
auto *r = static_cast<Register*>(simplify_load_var_object_size_c(&cenv, instr));
2803+
sync_c_env(cenv);
2804+
if (r) return r;
28012805
return simplifyLoadVarObjectSize(env, instr);
2806+
}
28022807

28032808
case Opcode::kBinaryOp:
28042809
return simplifyBinaryOp(env, static_cast<const BinaryOp*>(instr));

Python/jit/hir/simplify_c.c

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@
1212
extern HirType hir_register_type(void *reg);
1313
extern void *hir_func_alloc_register(void *func);
1414
extern void hir_c_insert_before(void *new_instr, void *before);
15+
extern HirType hir_output_type(void *instr);
1516

1617
/* ---- SimplifyEnv: C equivalent of the C++ Env struct ---- */
1718

1819
void *simplify_env_emit(SimplifyEnv *env, void *new_instr) {
1920
env->optimized = 1;
2021
hir_c_set_bytecode_offset(new_instr, env->bc_off);
2122
hir_c_insert_before(new_instr, env->cursor_instr);
22-
return hir_c_output(new_instr);
23+
void *out = hir_c_output(new_instr);
24+
if (out) {
25+
HirType out_type = hir_output_type(new_instr);
26+
hir_reg_set_type(out, out_type);
27+
}
28+
return out;
2329
}
2430

2531
void *simplify_env_emit_load_const(SimplifyEnv *env, HirType type) {
@@ -157,36 +163,6 @@ void *simplify_compare_c(SimplifyEnv *env, const void *instr) {
157163
}
158164
}
159165

160-
/* Bool == Bool or Bool != Bool → PrimitiveCompare + PrimitiveBoxBool */
161-
HirType t_bool = HIR_TYPE_SIMPLE(0x00000000002ULL, HIR_TYPE_LIFETIME_TOP);
162-
if (hir_type_is_subtype(left_type, t_bool) &&
163-
hir_type_is_subtype(right_type, t_bool) &&
164-
(op == 2 || op == 3)) {
165-
/* PrimitiveCompareOp::kEqual=4, kNotEqual=5 match CompareOp values */
166-
int32_t prim_op = (op == 2) ? 4 : 5;
167-
simplify_env_emit_use_type(env, left, t_bool);
168-
simplify_env_emit_use_type(env, right, t_bool);
169-
void *result = simplify_env_emit_primitive_compare(env, prim_op, left, right);
170-
return simplify_env_emit_primitive_box_bool(env, result);
171-
}
172-
173-
HirType t_float_exact = HIR_TYPE_SIMPLE(0x00000008000ULL, HIR_TYPE_LIFETIME_TOP);
174-
HirType t_long_exact = HIR_TYPE_SIMPLE(0x00000010000ULL, HIR_TYPE_LIFETIME_TOP);
175-
176-
/* Float comparison */
177-
if (hir_type_is_subtype(left_type, t_float_exact) &&
178-
hir_type_is_subtype(right_type, t_float_exact) &&
179-
op != 6 && op != 7 && op != 10) { /* not In/NotIn/ExcMatch */
180-
return simplify_env_emit_float_compare(env, op, left, right);
181-
}
182-
183-
/* Long comparison */
184-
if (hir_type_is_subtype(left_type, t_long_exact) &&
185-
hir_type_is_subtype(right_type, t_long_exact) &&
186-
op != 6 && op != 7 && op != 10) {
187-
return simplify_env_emit_long_compare(env, op, left, right);
188-
}
189-
190166
return NULL;
191167
}
192168

@@ -203,6 +179,28 @@ void *simplify_int_convert_c(SimplifyEnv *env, const void *instr) {
203179
return NULL;
204180
}
205181

182+
/* ---- simplifyLoadVarObjectSize (partial — known object path) ----
183+
* If input is a known tuple/bytes object, fold to constant ob_size. */
184+
void *simplify_load_var_object_size_c(SimplifyEnv *env, const void *instr) {
185+
void *obj_reg = hir_c_get_operand(instr, 0);
186+
HirType obj_type = hir_register_type(obj_reg);
187+
188+
HirType t_tuple_exact = HIR_TYPE_SIMPLE(0x00000040000ULL, HIR_TYPE_LIFETIME_TOP);
189+
HirType t_bytes_exact = HIR_TYPE_SIMPLE(0x00000002000ULL, HIR_TYPE_LIFETIME_TOP);
190+
191+
if (hir_type_has_value_spec(&obj_type, t_tuple_exact) ||
192+
hir_type_has_value_spec(&obj_type, t_bytes_exact)) {
193+
PyObject *obj = hir_type_as_object(&obj_type);
194+
if (obj != NULL) {
195+
Py_ssize_t size = ((PyVarObject *)obj)->ob_size;
196+
simplify_env_emit_use_type(env, obj_reg, obj_type);
197+
HirType output_type = hir_register_type(hir_c_output(instr));
198+
return simplify_env_emit_load_const(env, make_cint_type(output_type, (intptr_t)size));
199+
}
200+
}
201+
return NULL;
202+
}
203+
206204
/* ---- simplifyIsNegativeAndErrOccurred ----
207205
* If input is a LoadConst, we know no exception is active → result is 0. */
208206
void *simplify_is_neg_and_err_c(SimplifyEnv *env, const void *instr) {

Python/jit/hir/simplify_c.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void *simplify_cint_to_cbool_c(SimplifyEnv *env, const void *instr);
3737
void *simplify_cond_branch_const_c(SimplifyEnv *env, const void *instr);
3838
void *simplify_compare_c(SimplifyEnv *env, const void *instr);
3939
void *simplify_is_neg_and_err_c(SimplifyEnv *env, const void *instr);
40+
void *simplify_load_var_object_size_c(SimplifyEnv *env, const void *instr);
4041

4142
#ifdef __cplusplus
4243
}

0 commit comments

Comments
 (0)