Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information