gh-104615: don't make unsafe swaps in apply_static_swaps (#104620)

This commit is contained in:
Carl Meyer 2023-05-18 15:22:03 -06:00 committed by GitHub
parent dcdc90d384
commit 0589c6a4d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 95 additions and 20 deletions

View file

@ -7996,7 +7996,7 @@ finally:
}
PyObject *
_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts, int nlocals)
{
PyObject *res = NULL;
PyObject *const_cache = PyDict_New();
@ -8008,7 +8008,7 @@ _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
if (instructions_to_cfg(instructions, &g) < 0) {
goto error;
}
int code_flags = 0, nlocals = 0, nparams = 0, firstlineno = 1;
int code_flags = 0, nparams = 0, firstlineno = 1;
if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals,
nparams, firstlineno) < 0) {
goto error;

View file

@ -1293,6 +1293,11 @@ swaptimize(basicblock *block, int *ix)
(opcode) == STORE_FAST_MAYBE_NULL || \
(opcode) == POP_TOP)
#define STORES_TO(instr) \
(((instr).i_opcode == STORE_FAST || \
(instr).i_opcode == STORE_FAST_MAYBE_NULL) \
? (instr).i_oparg : -1)
static int
next_swappable_instruction(basicblock *block, int i, int lineno)
{
@ -1344,6 +1349,23 @@ apply_static_swaps(basicblock *block, int i)
return;
}
}
// The reordering is not safe if the two instructions to be swapped
// store to the same location, or if any intervening instruction stores
// to the same location as either of them.
int store_j = STORES_TO(block->b_instr[j]);
int store_k = STORES_TO(block->b_instr[k]);
if (store_j >= 0 || store_k >= 0) {
if (store_j == store_k) {
return;
}
for (int idx = j + 1; idx < k; idx++) {
int store_idx = STORES_TO(block->b_instr[idx]);
if (store_idx >= 0 && (store_idx == store_j || store_idx == store_k)) {
return;
}
}
}
// Success!
INSTR_SET_OP0(swap, NOP);
cfg_instr temp = block->b_instr[j];