summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Sweeney <36520290+sweeneyde@users.noreply.github.com>2023-12-01 00:35:49 (GMT)
committerGitHub <noreply@github.com>2023-12-01 00:35:49 (GMT)
commita99305e7fbbc9e67a50091583ac1e1e625963663 (patch)
tree5e841bfc744117c80890e112d84e892f26a5e763
parent4c9da4c964a62c2972fa40b30ab11f19f89178f4 (diff)
downloadcpython-a99305e7fbbc9e67a50091583ac1e1e625963663.zip
cpython-a99305e7fbbc9e67a50091583ac1e1e625963663.tar.gz
cpython-a99305e7fbbc9e67a50091583ac1e1e625963663.tar.bz2
[3.12] gh-112356: LOAD_GLOBAL can only include one PUSH_NULL (#112566)
-rw-r--r--Lib/test/test_peepholer.py21
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-11-30-23-47-56.gh-issue-112356.g2BqyK.rst1
-rw-r--r--Python/flowgraph.c4
3 files changed, 24 insertions, 2 deletions
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 0aabce8..02e43d1 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -1075,5 +1075,26 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
]
self.cfg_optimization_test(insts, insts, consts=list(range(3)), nlocals=1)
+ def test_only_one_push_null_per_load_global(self):
+ # When optimizing func()(), a second pass shouldn't
+ # let the LOAD_GLOBAL absorb another PUSH_NULL.
+ before = [
+ ('PUSH_NULL', 0, 1),
+ ('PUSH_NULL', 0, 1),
+ ('LOAD_GLOBAL', 0, 1),
+ ('CALL', 0, 1),
+ ('CALL', 0, 1),
+ ('RETURN_VALUE', 0, 1),
+ ]
+ after = [
+ ('PUSH_NULL', 0, 1),
+ ('LOAD_GLOBAL', 1, 1),
+ ('CALL', 0, 1),
+ ('CALL', 0, 1),
+ ('RETURN_VALUE', 0, 1),
+ ]
+ self.cfg_optimization_test(before, expected_insts=after, consts=[])
+ self.cfg_optimization_test(after, expected_insts=after, consts=[])
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-30-23-47-56.gh-issue-112356.g2BqyK.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-30-23-47-56.gh-issue-112356.g2BqyK.rst
new file mode 100644
index 0000000..0bb8eaf
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-30-23-47-56.gh-issue-112356.g2BqyK.rst
@@ -0,0 +1 @@
+Stopped erroneously deleting a ``LOAD_NULL`` bytecode instruction when optimized twice.
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index afcae31..b53e771 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -1554,9 +1554,9 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
case KW_NAMES:
break;
case PUSH_NULL:
- if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) {
+ if (nextop == LOAD_GLOBAL && (bb->b_instr[i+1].i_oparg & 1) == 0) {
INSTR_SET_OP0(inst, NOP);
- inst[1].i_oparg |= 1;
+ bb->b_instr[i+1].i_oparg |= 1;
}
break;
default: