PossibleContents is not a lattice
IIUC, we have this structure:
Type(i32)
/ \
Global("g1", i32) Global("g2", i32)
| X |
Literal(1) Literal(2)
There is no unique least upper bound of the two literals and there is no unique greatest lower bound of the two globals. This is a problem because union and intersect are supposed to calculate unique least upper / greatest lower bounds.
I think there is a probably a way to solve this, but I'll have to think on it.
I ran into this while trying to simplify and complete the implementation of intersect as part of the investigation suggested here: https://github.com/WebAssembly/binaryen/pull/7538/files#r2054860951
Isn't it
Type(i32)
/ / \ \
Global("g1", i32) Global("g2", i32) Literal(1) Literal(2)
\ \ / /
None
?
The union of a global and a literal is neither a global or a literal, it is an unknown thing of the shared type, and the intersection of a global and a literal is empty (same as unioning/intersecting two different globals, or two different literals).
If I'm reading the code correctly, haveIntersection and isSubContents will happily report that Literal(1) < Global("g1", i32), and since intersect exits early when isSubContents is true, it has this behavior as well.
Ah, there might be bugs in haveIntersection and isSubContents then. But intersect() explicitly says it isn't ready for Globals yet,
https://github.com/WebAssembly/binaryen/blob/6e7a4a0507986d067550911a3bac59ce76f8453c/src/ir/possible-contents.cpp#L145-L147
edit: I guess it only checks that on other, so there might be a bug there too