In the test case, we are trying to merge a dead path in a live target block 
which is unexpected and we fail with an assertion failure.

We call `Parse::do_acmp()` with `BoolTest::ne`. This means that the target 
block is reached over `ne_region`, which collects all the branching paths, and 
the fall-through block is `eq_region`, which collects all the fall-through 
paths. 

We emit several checks to see if we need to branch off and capture those in 
`ne_region`. In the test case, we either fold such a branch directly with the 
available information or we emit an uncommon trap in which case we also will 
not branch off to the target block. At the end of `do_acmp`, we only collected 
dead paths in the `ne_region` and thus are left with only `top` inputs. This 
means that we will not branch off to the target block and will fall through. We 
transform the `ne_region` with `top` inputs only, get `top` back and set it as 
current control:
https://github.com/openjdk/valhalla/blob/6adeca933a1361c6f44f51c9c266bd1a20a42380/src/hotspot/share/opto/parse2.cpp#L2436
Nothing unusual, this is perfectly fine to signal that this path is dead. So 
far, so good.

Since `do_acmp` handles both the `BoolTest::ne` and `BoolTest::eq` case, we 
actually need to swap the fall-through control to be the `eq_region` instead:
https://github.com/openjdk/valhalla/blob/6adeca933a1361c6f44f51c9c266bd1a20a42380/src/hotspot/share/opto/parse2.cpp#L2447-L2450

Before doing that, we merge the `ne_region` into the target block:
https://github.com/openjdk/valhalla/blob/6adeca933a1361c6f44f51c9c266bd1a20a42380/src/hotspot/share/opto/parse2.cpp#L2441-L2445

However, if the target block is live by already having merged another block as 
in the test case, we will merge a dead path with a live path. This is not 
anticipated by `merge()` and we fail with an assertion failure: The caller 
needs to make sure to only call `merge()` with live paths.

The solution is straight forward: Only `merge()` if we have not `stopped()`. 
Otherwise, mark the block as handled and do nothing.

Thanks,
Christian

---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

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

Commit messages:
 - 8386602: [lworld] C2: assert(n != top() || r->in(pnum) == top()) failed: 
live value must not be garbage

Changes: https://git.openjdk.org/valhalla/pull/2618/files
  Webrev: https://webrevs.openjdk.org/?repo=valhalla&pr=2618&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8386602
  Stats: 23 lines in 2 files changed: 21 ins; 1 del; 1 mod
  Patch: https://git.openjdk.org/valhalla/pull/2618.diff
  Fetch: git fetch https://git.openjdk.org/valhalla.git pull/2618/head:pull/2618

PR: https://git.openjdk.org/valhalla/pull/2618

Reply via email to