diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-04-22 07:14:06 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-04-22 07:14:06 -0700 |
commit | 1e74c95c57e9e5c6e4650b9817de265cfbc8afe2 (patch) | |
tree | afd03d6e6ced288854542c1f8071e17b2518121f /tests/015/split.tl | |
parent | 43303f6ce29bf502644c27115b0d9b680142f989 (diff) | |
download | txr-1e74c95c57e9e5c6e4650b9817de265cfbc8afe2.tar.gz txr-1e74c95c57e9e5c6e4650b9817de265cfbc8afe2.tar.bz2 txr-1e74c95c57e9e5c6e4650b9817de265cfbc8afe2.zip |
compiler: bug: eliminate-frame not initializing tregs.
In eliminate-frame, our stategy of replacing vregs with tregs
assumes that the newly minted tregs are initialized to nil.
This is true if the block is executed only once, but not true
if it's in the middle of a loop, where the previous
iteration's treg values can be present. This results in
miscompilation of code like
(when-match (@x @(all @x)) '(1 (1 2)) x)
which wrongly returns 1 instead of nil starting at
optimization level 2.
* share/txr/stdlib/compiler.tl (struct compiler): New slot,
loop-nest, indicating the loop nesting level.
(compiler eliminate-frame): add instructions to the start of
the block of code to null out all the tregs that we allocated
for replacing vregs. We do this only when compiling the
repeated parts of a loop, as indicated by a positive value
of loop-nest.
(comp-for): Increment loop-nest before compiling the repeated
parts of the loop; decrement it afterward.
Diffstat (limited to 'tests/015/split.tl')
0 files changed, 0 insertions, 0 deletions