Skip to content

Type propagation: just because something is const doesn't mean it automatically matches the type #115859

Description

@Fidget-Spinner

Bug report

Bug description:

See log files for failure:

https://github.com/python/cpython/actions/runs/8021737661/job/21914497578

An example failure from my Windows machine:

Assertion failed: PyFloat_CheckExact(sym_get_const(left)), file C:\Users\Ken\Documents\GitHub\cpython\Python\tier2_redundancy_eliminator_cases.c.h, line 279
Fatal Python error: Aborted

Just because a constant is present, doesn't mean it's the right type. In such a case, I think we should bail from the abstract interpreter, because it's a guaranteed deopt.

E.g.

op(_GUARD_BOTH_FLOAT, (left, right--left, right)) {
if (sym_matches_type(left, &PyFloat_Type) &&sym_matches_type(right, &PyFloat_Type)) {
REPLACE_OP(this_instr, _NOP, 0 ,0);
}
sym_set_type(left, &PyFloat_Type);
sym_set_type(right, &PyFloat_Type);
}

should become

op(_GUARD_BOTH_FLOAT, (left, right--left, right)) {
if (sym_matches_type(left, &PyFloat_Type) &&sym_matches_type(right, &PyFloat_Type)) {
REPLACE_OP(this_instr, _NOP, 0 ,0);
}
if (sym_is_const(left)) {
if (!sym_const_is_type(left, &PyFloat_Type) goto guaranteed_deopt;
}
if (sym_is_const(right)) {
if (!sym_const_is_type(right, &PyFloat_Type) goto guaranteed_deopt;
}
sym_set_type(left, &PyFloat_Type);
sym_set_type(right, &PyFloat_Type);
}

While

op(_BINARY_OP_ADD_FLOAT, (left, right--res)) {
if (sym_is_const(left) &&sym_is_const(right)) {
assert(PyFloat_CheckExact(sym_get_const(left)));
assert(PyFloat_CheckExact(sym_get_const(right)));
PyObject*temp=PyFloat_FromDouble(
PyFloat_AS_DOUBLE(sym_get_const(left)) +PyFloat_AS_DOUBLE(sym_get_const(right)));
ERROR_IF(temp==NULL, error);
OUT_OF_SPACE_IF_NULL(res=sym_new_const(ctx, temp));
// TODO gh-115506:// replace opcode with constant propagated one and update tests!
}
else {
OUT_OF_SPACE_IF_NULL(res=sym_new_known_type(ctx, &PyFloat_Type));
}
}

should become

op(_BINARY_OP_ADD_FLOAT, (left, right--res)) {
if (sym_is_const(left) &&sym_is_const(right)) {
if(!PyFloat_CheckExact(sym_get_const(left))) {
goto guaranteed_deopt;
}
if(!PyFloat_CheckExact(sym_get_const(right))) {
goto guaranteed_deopt;
}
PyObject*temp=PyFloat_FromDouble(
PyFloat_AS_DOUBLE(sym_get_const(left)) +PyFloat_AS_DOUBLE(sym_get_const(right)));
ERROR_IF(temp==NULL, error);
OUT_OF_SPACE_IF_NULL(res=sym_new_const(ctx, temp));
// TODO gh-115506:// replace opcode with constant propagated one and update tests!
}
else {
OUT_OF_SPACE_IF_NULL(res=sym_new_known_type(ctx, &PyFloat_Type));
}
}

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

Metadata

Metadata

Labels

type-bugAn unexpected behavior, bug, or error

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions