[lworld] RFR: 8367245: [lworld] C2 compilation fails with "Missed optimization opportunity in PhaseIterGVN"

Quan Anh Mai qamai at openjdk.org
Thu Nov 6 09:20:31 UTC 2025


On Tue, 4 Nov 2025 14:02:10 GMT, Marc Chevalier <mchevalier at openjdk.org> 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


More information about the valhalla-dev mailing list