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...

I disagree. The issue only surfaces in this particular occasion does not mean 
it will not appear in other circumstances, possibly in the future. Even if the 
code is there on purpose, it seems that the purpose is executed incorrectly.

Additionally, an empty speculative type is supposed to mean that the path is 
speculatively unreachable, which is not the case here. So, another approach may 
be to fix the injection of speculative and assert that we should not obtain an 
empty speculative type?

-------------

PR Comment: https://git.openjdk.org/valhalla/pull/1717#issuecomment-3496085483

Reply via email to