RFR: 8351889: C2 crash: assertion failed: Base pointers must match (addp 344)

Roland Westrelin roland at openjdk.org
Thu May 22 08:40:08 UTC 2025


The test case has an out of loop `Store` with an `AddP` address
expression that has other uses and is in the loop body. Schematically,
only showing the address subgraph and the bases for the `AddP`s:


Store#195 -> AddP#133 -> AddP#134 -> CastPP#110
                     -> CastPP#110


Both `AddP`s have the same base, a `CastPP` that's also in the loop
body.

That loop is a counted loop and only has 3 iterations so is fully
unrolled. First, one iteration is peeled:


                                /-> CastPP#110
Store#195 -> Phi#360 -> AddP#133 -> AddP#134 -> CastPP#110
                    -> AddP#277 -> AddP#278 -> CastPP#283
                                -> CastPP#283



The `AddP`s and `CastPP` are cloned (because in the loop body). As
part of peeling, `PhaseIdealLoop::peeled_dom_test_elim()` is
called. It finds the test that guards `CastPP#283` in the peeled
iteration dominates and replaces the test that guards `CastPP#110`
(the test in the peeled iteration is the clone of the test in the
loop). That causes `CastPP#110`'s control to be updated to that of the
test in the peeled iteration and to be yanked from the loop. So now
`CastPP#283` and `CastPP#110` have the same inputs.

Next unrolling happens:


                                           /-> CastPP#110
                               /-> AddP#400 -> AddP#401 -> CastPP#110
Store#195 -> Phi#360 -> Phi#477 -> AddP#133 -> AddP#134 -> CastPP#110
                  \                        -> CastPP#110
                   -> AddP#277 -> AddP#278 -> CastPP#283
                               -> CastPP#283



`AddP`s are cloned once more but not the `CastPP`s because they are
both in the peeled iteration now. A new `Phi` is added.

Next igvn runs. It's going to push the `AddP`s through the `Phi`s.

Through `Phi#477`:



                                /-> CastPP#110
Store#195 -> Phi#360 -> AddP#510 -> Phi#509 -> AddP#401 -> CastPP#110
                  \                        -> AddP#134 -> CastPP#110
                   -> AddP#277 -> AddP#278 -> CastPP#283
                               -> CastPP#283



Through `Phi#360`:


                                           /-> AddP#134 -> CastPP#110
                                /-> Phi#509 -> AddP#401 -> CastPP#110
Store#195 -> AddP#516 -> Phi#515 -> AddP#278 -> CastPP#283
                     -> Phi#514 -> CastPP#283
                                -> CastP#110


Then `Phi#514` which has 2 `CastPP`s as input with identical inputs is
transformed into another `CastPP` at the `Phi` constrol with the data
control of the `CastPP` as input. `PhiNode::unique_input()` with
`uncast = true` is where that happens. That's where things go wrong I
think.


                                           /-> AddP#134 -> CastPP#110
                                /-> Phi#509 -> AddP#401 -> CastPP#110
Store#195 -> AddP#516 -> Phi#515 -> AddP#278 -> CastPP#283
                     -> CastPP#529


Next `AddP`s pushed through `Phi#509`:


                                /-> AddP#536 -> CastPP#110
Store#195 -> AddP#516 -> Phi#515 -> AddP#278 -> CastPP#283
                     -> CastPP#529


`CastPP#110` and `CastPP#283` commoned (they have the same inputs):


                                /-> AddP#536 -> CastPP#110
Store#195 -> AddP#516 -> Phi#515 -> AddP#278 -> CastPP#110
                     -> CastPP#529


Finally, AddPs pushed through `Phi#515`:


Store#195 -> AddP#516 -> AddP#544 -> CastPP#110
                     -> CastPP#529


And we end up with 2 `AddP`s with different bases. The 2 `CastPP`s
have the same data input but not same control and igvn can't common
them.


The fix I propose is to delay the call to `PhiNode::unique_input()`
with `uncast = true` if the `Phi`'s inputs are cast nodes and have yet
to be processed by igvn. This causes identical `CastPP`s to common and
then only the `Phi` has 2 identical inputs is transformed to that
input (rather than have a new `CastPP`s be created at a different
control).

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

Commit messages:
 - more
 - test
 - fix

Changes: https://git.openjdk.org/jdk/pull/25386/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25386&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8351889
  Stats: 99 lines in 3 files changed: 99 ins; 0 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/25386.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/25386/head:pull/25386

PR: https://git.openjdk.org/jdk/pull/25386


More information about the hotspot-compiler-dev mailing list