On Tue, 4 Nov 2025 14:02:10 GMT, Marc Chevalier <[email protected]> wrote:
> # Analysis > ## Obervationally > ### IGVN > During IGVN, in `PhiNode::Value`, a `PhiNode` has 2 inputs. Their types are: > > in(1): java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 > (compiler/valhalla/inlinetypes/MyInterface):exact * (inline_depth=4)) > in(2): java/lang/Object * (speculative=null) > > We compute the join (HS' meet): > https://github.com/openjdk/valhalla/blob/412ec882767d3ee1792d1e0f98da54ff800c60ce/src/hotspot/share/opto/cfgnode.cpp#L1310-L1317 > > t=java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 > (compiler/valhalla/inlinetypes/MyInterface):exact *) > > But the current `_type` (of the `PhiNode` as a `TypeNode`) is > > _type=java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue3 > (compiler/valhalla/inlinetypes/MyInterface):exact *) > > We filter `t` by `_type` > https://github.com/openjdk/valhalla/blob/412ec882767d3ee1792d1e0f98da54ff800c60ce/src/hotspot/share/opto/cfgnode.cpp#L1332 > and we get > > ft=java/lang/Object * > > which is what we return. After the end of `Value`, the returned becomes the > new `PhiNode`'s `_type`. > https://github.com/openjdk/valhalla/blob/412ec882767d3ee1792d1e0f98da54ff800c60ce/src/hotspot/share/opto/phaseX.cpp#L2150-L2164 > and > https://github.com/openjdk/valhalla/blob/412ec882767d3ee1792d1e0f98da54ff800c60ce/src/hotspot/share/opto/node.cpp#L1127-L1133 > > > ### Verification > On verification, `in(1)`, `in(2)` have the same value, so does `t`. But this > time > > _type=java/lang/Object * > > and so after filtering `t` by (new) `_type` and we get > > ft=java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 > (compiler/valhalla/inlinetypes/MyInterface):exact *) > > which is retuned. Verification gets angry because the new `ft` is not the > same as the previous one. > > ## But why?! > ### Details on type computation > In short, we are doing > > t = typeof(in(1)) / typeof(in(2)) > ft = t /\ _type (* IGVN *) > ft' = t /\ ft (* Verification *) > > and observing that `ft != ft'`. It seems our lattice doesn't ensure `(a /\ b) > /\ b = a /\ b` which is problematic for this kind of verfication that will > just "try again and see if something change". > > To me, the surprising fact was that the intersection > > java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 > (compiler/valhalla/inlinetypes/MyInterface):exact *) > /\ > _type=java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue3 > (compiler/valhalla/inlinetypes/MyInterface):exact *) > ~> > java/lang/Object * > > What happened to the speculative type? Both `MyVal... Do I understand right that 1) `Value` is run first the `Phi` has 2 different nodes as inputs. 2) then the `Phi`'s input change and are the same 3) something breaks at verification time? If that's correct why don't we run `Value` again after 2)? With: in(1): java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 (compiler/valhalla/inlinetypes/MyInterface):exact * (inline_depth=4)) in(2): java/lang/Object * (speculative=null) How can the meet be `t=java/lang/Object * (speculative=compiler/valhalla/inlinetypes/MyValue2 (compiler/valhalla/inlinetypes/MyInterface):exact *)`? Is one of the region's input `top`? ------------- PR Comment: https://git.openjdk.org/valhalla/pull/1717#issuecomment-3486782400
