https://github.com/python/cpython/commit/5e74d920c80f4bf4d44d84838aed81423c42b9dd
commit: 5e74d920c80f4bf4d44d84838aed81423c42b9dd
branch: main
author: Neko Asakura <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-13T20:56:29+08:00
summary:

gh-148285: Allow recording uops after specializing uops (GH-148482)

files:
M Lib/test/test_generated_cases.py
M Tools/cases_generator/analyzer.py

diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index 57991b5b6b859c..bb831fa984c34b 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -1890,6 +1890,64 @@ def test_reassigning_dead_inputs(self):
         """
         self.run_cases_test(input, output)
 
+    def test_recording_after_specializing_with_cache(self):
+        input = """
+        specializing op(SPEC, (counter/1 --)) {
+            spam;
+        }
+
+        tier2 op(REC, (--)) {
+            RECORD_VALUE(0);
+        }
+
+        op(BODY, (--)) {
+            ham;
+        }
+
+        macro(OP) = SPEC + unused/2 + REC + BODY;
+        """
+        output = """
+        TARGET(OP) {
+            #if _Py_TAIL_CALL_INTERP
+            int opcode = OP;
+            (void)(opcode);
+            #endif
+            _Py_CODEUNIT* const this_instr = next_instr;
+            (void)this_instr;
+            frame->instr_ptr = next_instr;
+            next_instr += 4;
+            INSTRUCTION_STATS(OP);
+            // SPEC
+            {
+                uint16_t counter = read_u16(&this_instr[1].cache);
+                (void)counter;
+                spam;
+            }
+            /* Skip 2 cache entries */
+            // BODY
+            {
+                ham;
+            }
+            DISPATCH();
+        }
+        """
+        self.run_cases_test(input, output)
+
+    def test_recording_after_non_specializing(self):
+        input = """
+        op(REGULAR, (--)) {
+            spam;
+        }
+
+        tier2 op(REC, (--)) {
+            RECORD_VALUE(0);
+        }
+
+        macro(OP) = REGULAR + REC;
+        """
+        with self.assertRaisesRegex(SyntaxError, "Recording uop"):
+            self.run_cases_test(input, "")
+
 
 class TestGeneratedAbstractCases(unittest.TestCase):
     def setUp(self) -> None:
diff --git a/Tools/cases_generator/analyzer.py 
b/Tools/cases_generator/analyzer.py
index 6ba9c43ef1f0c3..100de4c7250907 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -1132,7 +1132,9 @@ def add_macro(
     macro: parser.Macro, instructions: dict[str, Instruction], uops: dict[str, 
Uop]
 ) -> None:
     parts: list[Part] = []
-    first = True
+    # Track the last non-specializing uop seen, so that recording uops
+    # can follow specializing ones without triggering the position check.
+    prev_uop: Uop | None = None
     for part in macro.uops:
         match part:
             case parser.OpName():
@@ -1144,12 +1146,14 @@ def add_macro(
                             f"No Uop named {part.name}", macro.tokens[0]
                         )
                     uop = uops[part.name]
-                    if uop.properties.records_value and not first:
+                    if uop.properties.records_value and prev_uop is not None:
                         raise analysis_error(
-                            f"Recording uop {part.name} must be first in 
macro",
+                            f"Recording uop {part.name} is not allowed "
+                            f"after non-specializing uops in macro",
                             macro.tokens[0])
                     parts.append(uop)
-                    first = False
+                    if "specializing" not in uop.annotations:
+                        prev_uop = uop
             case parser.CacheEffect():
                 parts.append(Skip(part.size))
             case _:

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to