Repository navigation
compiler can incorrectly optimize a run of stores to the same name preceded by a SWAP #104615
Copy link
Copy link
Closed
Closed
Copy link
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)release-blockertype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on May 18, 2023 I see two options for fixing this:
- Change
apply_static_swapsto also track store locations and consider instructions not swappable if they store to the same location. - Add redundant store elimination, so prior to
apply_static_swapswe would reduceSWAP 2; STORE_FAST a; STORE_FAST atoSWAP_2; POP_TOP; STORE_FAST a, whichapply_static_swapswould correctly optimize toSTORE_FAST a; POP_TOP.
Probably the ideal is to do both; (2) because it results in the best compiler output, and (1) because it is more robust and avoids implicit dependency of one optimization on another.
- Change
This is definitely a bug in
apply_static_swaps:3.10:
>>> def f(x, y): ... a, a = x, y ... return a ... >>> f(True, False) False
3.11:
>>> def f(x, y): ... a, a = x, y ... return a ... >>> f(True, False) True
Reacted by Carl Meyer- added3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on May 18, 2023 I'm considering this issue fixed by the merged PR. I filed #104635 for the separate question of improving compiler output in these cases with dead store elimination.
Reacted by Jelle Zijlstra- moved this from Todo to Done in Release and Deferred blockers 🚫
on May 18, 2023
Metadata
Metadata
Assignees
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)release-blockertype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Projects
- StatusShow more project fieldsDone
If the
apply_static_swapsoptimization in the compiler sees the instruction sequenceSWAP 2; STORE_FAST a; STORE_FAST a, it will optimize that by removing theSWAPand swapping the two instructions, resulting inSTORE_FAST a; STORE_FAST a.But of course, in this case the two instructions are identical, and their ordering matters because they store to the same location. So this change results in the wrong value being stored to
a.This was exposed by comprehension inlining, since it can result in this bytecode sequence for code in the form
a = [1 for a in [0]](where the firstSTORE_FAST ais restoring the previous value ofafrom before the comprehension, if any, and the secondSTORE_FAST ais storing the result of the comprehension toa.).Linked PRs