You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to ensure that function exits have a line number, the compiler duplicates small exit blocks which (1) do not have a line number in any instruction and (2) have more than one predecessor. Since these blocks are jump targets (at least one predecessor reaches this block via a jump or exception), they need to have labels assigned to them. This was missing, and is added in the attached PR.
This begs the question "how did this ever work?"
The assertion that fails here is in a piece of code that transforms a conditional backwards jump into a conditional forward jump followed by an unconditional backward jump (because all backward jumps are unconditional). It is this code that asserted the label. In general the labels are not that useful this late in the compiler's process, they are mostly used in the code generation phase, before we have the CFG with a direct pointer from a jump to its target block.
The typical case of a small basic block is the "return None" of a function, and it is not a target of a conditional backward branch - this is what made this edge case rare.
@iritkatriel thank you for fixing this bug.
I would also like to mention that I automatically minimized the example with pysource-minimize. maybe you will find that useful too.
Activity
JelleZijlstra commentedon Sep 20, 2023
Confirmed on main, 3.11 is fine. cc @iritkatriel for
flowgraph.c.I'll try to bisect but not sure I'll have time to finish the bisect.
iritkatriel commentedon Sep 20, 2023
I'm looking. I don't think bisecting will help - the jump targets labels are new so you'll probably get to the large PR that added them.
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…
iritkatriel commentedon Sep 20, 2023
In order to ensure that function exits have a line number, the compiler duplicates small exit blocks which (1) do not have a line number in any instruction and (2) have more than one predecessor. Since these blocks are jump targets (at least one predecessor reaches this block via a jump or exception), they need to have labels assigned to them. This was missing, and is added in the attached PR.
This begs the question "how did this ever work?"
The assertion that fails here is in a piece of code that transforms a conditional backwards jump into a conditional forward jump followed by an unconditional backward jump (because all backward jumps are unconditional). It is this code that asserted the label. In general the labels are not that useful this late in the compiler's process, they are mostly used in the code generation phase, before we have the CFG with a direct pointer from a jump to its target block.
The typical case of a small basic block is the "return None" of a function, and it is not a target of a conditional backward branch - this is what made this edge case rare.
iritkatriel commentedon Sep 20, 2023
@15r10nk - Thank you for finding this and for the tiny repro.
gh-109627: duplicated smalll exit blocks need to be assigned jump tar…
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…
15r10nk commentedon Sep 21, 2023
@iritkatriel thank you for fixing this bug.
I would also like to mention that I automatically minimized the example with pysource-minimize. maybe you will find that useful too.
[3.12] gh-109627: duplicated small exit blocks need to be assigned ju…
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…
pythongh-109627: duplicated smalll exit blocks need to be assigned ju…