Join ceilings incorrectly getting placed outside value lambdas by SetLevels
This is a latent bug, so there's no test case.
Given code like
let f = \x y z -> e1 in e2
we have SetLevels
put a “join ceiling” around e1
to be sure that we don't let a join point float out, since any jump to that join point from e1
would be invalid. However, an oversight in lvlFloatRhs
has us putting the join ceiling around the lambdas instead—in other words, it appears that we might produce
let f =
join j = ... in \x y z -> ... jump j ...
in e2
(which is wrong because you can't jump out of a lambda) rather than
let f =
\x y z -> join j = ... in ... jump j ...
in e2
As it happens, this bug is latent because of the way FloatOut
and SetLevels
interact. FloatOut
correctly understands where the join ceiling //should// be. Then, at each join ceiling, FloatOut
drops all bindings marked “float me to the nearest join ceiling,” so if j
is so marked, the latter example (the correct one) is the result and not the former. Nonetheless, lvlFloatRhs
as written is clearly wrong.
(This of course illustrates a shortcoming of the “join ceiling” scheme, at least as implemented: we rely on FloatOut
and SetLevels
agreeing on where the join ceilings are. It's easy to specify where they //should// be, but since there are two modules implementing them, we have twice the opportunities to get it wrong.)
Trac metadata
Trac field | Value |
---|---|
Version | 8.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |