Skip to content

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

@Fidget-Spinner

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