https://github.com/python/cpython/commit/5e96e4fca80a8cd25da6b469b25f8f5a514de8be commit: 5e96e4fca80a8cd25da6b469b25f8f5a514de8be branch: main author: Tomas R. <tomas.ro...@gmail.com> committer: Fidget-Spinner <kenjin4...@gmail.com> date: 2025-04-27T02:47:55+08:00 summary:
gh-131798: JIT: Propagate the result in `_BINARY_OP_SUBSCR_TUPLE_INT` (GH-133003) files: A Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst M Lib/test/test_capi/test_opt.py M Python/optimizer_bytecodes.c M Python/optimizer_cases.c.h diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0047306ae422db..7e0c60d5522402 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1923,6 +1923,23 @@ def testfunc(n): self.assertNotIn("_GUARD_TOS_INT", uops) self.assertIn("_CALL_LEN", uops) + def test_binary_op_subscr_tuple_int(self): + def testfunc(n): + x = 0 + for _ in range(n): + y = (1, 2) + if y[0] == 1: # _COMPARE_OP_INT + _GUARD_IS_TRUE_POP are removed + x += 1 + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops) + self.assertNotIn("_COMPARE_OP_INT", uops) + self.assertNotIn("_GUARD_IS_TRUE_POP", uops) + def global_identity(x): return x diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst new file mode 100644 index 00000000000000..f4049240f7d15c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst @@ -0,0 +1,2 @@ +Propagate the return type of ``_BINARY_OP_SUBSCR_TUPLE_INT`` in JIT. Patch +by Tomas Roun diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 040e54479b722a..f862c9c8c6a840 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -370,6 +370,27 @@ dummy_func(void) { res = sym_new_type(ctx, &PyUnicode_Type); } + op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) { + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); + assert(index >= 0); + int tuple_length = sym_tuple_length(tuple_st); + if (tuple_length == -1) { + // Unknown length + res = sym_new_not_null(ctx); + } + else { + assert(index < tuple_length); + res = sym_tuple_getitem(ctx, tuple_st, index); + } + } + else { + res = sym_new_not_null(ctx); + } + } + op(_TO_BOOL, (value -- res)) { int already_bool = optimize_to_bool(this_instr, ctx, value, &res); if (!already_bool) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 9a5a362ec199a9..c92b036eb56463 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -617,8 +617,28 @@ } case _BINARY_OP_SUBSCR_TUPLE_INT: { + JitOptSymbol *sub_st; + JitOptSymbol *tuple_st; JitOptSymbol *res; - res = sym_new_not_null(ctx); + sub_st = stack_pointer[-1]; + tuple_st = stack_pointer[-2]; + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); + assert(index >= 0); + int tuple_length = sym_tuple_length(tuple_st); + if (tuple_length == -1) { + res = sym_new_not_null(ctx); + } + else { + assert(index < tuple_length); + res = sym_tuple_getitem(ctx, tuple_st, index); + } + } + else { + res = sym_new_not_null(ctx); + } stack_pointer[-2] = res; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com