Crash report
** is weird in that the type of the result depends on the values of the inputs. The logic for int/float power is:
def type_of_pow(lhs: float, rhs: float) -> type[complex]: if isinstance(lhs, int) and isinstance(rhs, int) and rhs >= 0: return int if lhs < 0 and not rhs.is_integer(): return complex return float
However, our optimizer wrongly assumes:
def type_of_pow(lhs: float, rhs: float) -> type[float]: if isinstance(lhs, int) and isinstance(rhs, int): return int return float
This means that tons of different poorly-chosen values can cause JIT code to crash:
import _testinternalcapi import itertools def f(a, b): for _ in range(_testinternalcapi.TIER2_THRESHOLD): a + b # Remove guards... a ** b + a # ...BOOM! for la, ra, lb, rb in itertools.product([1, -1, 1.0, -1.0, 0.5, -0.5], repeat=4): f(la, ra) f(lb, rb)
Normally we could just ignore the problem and produce an unknown type during abstract interpretation, but a ** containing at least one constant value is actually reasonably common (think x ** 2, 2 ** n, or s ** 0.5).
We should probably teach the optimizer how to handle these properly.