win64 fails a complicated test when run with the JIT in scipy
xref https://github.com/scipy/scipy/issues/15121 and the smaller reproducer in in https://gist.github.com/mattip/346234bc51a8a3afca10ea8929a53df0.
The problem only happens when PyPy JIT kicks in: eventually the python callback in dqegie is called with -1 as an argument instead of a valid value. The code works like this:
integrate(self, *args, depth=0)with depth = 0
this calls a scipy C function
_quadpack._qagie(func, bound, infbounds, args, full_output, epsabs, epsrel, limit)where
funcis a partial-wrapped version of
depth = 1,
argsis from the call, and the other arguments are float or int.
inside _qagie(), the C code calls a fortran function where
quadpack_f_tis the pointer to
void DQAGIE(quadpack_f_t f, double *bound, F_INT *inf, double *epsabs, double *epsrel, F_INT *limit, double *result, double *abserr, F_INT *neval, F_INT *ier, double *alist, double *blist, double *rlist, double *elist, F_INT *iord, F_INT *last);
DQAGIEdoes an approximation of the integral of
funcat various values, it ends up calling
the partial-wrapped call to integrate with
_quadpack._qagieagain, this time
funcis a pointer to a C function.
integrate is called once as
func = integrate(floatval, depth=1) func = c function func = c function func = c function ... func = c function func = c function func = c function func = integrate(floatval, depth=1) func = c function func = c function func = c function ... func = c function func = c function func = c function ...
At some point, when run with the JIT, the
func is called with is wrong: it is
-1.00 instead of other values. That value get "stuck" and the evaluation of the function fails. This can be seen in the last file in the gist.
I suspect there is some register corruption in the JIT: the calling convention expects a register to be preserved but it is corrupted. Another possibility is some kind of stack smashing, but I would expect that to be detected and crash the process.
@cfbolz suggested running the
rpython/jit/backend/test/test_random* tests, but I don't think they simulate a function call with so many arguments.