RFR(S): 8241900: Loop unswitching may cause dependence on null check to be lost

Roland Westrelin rwestrel at redhat.com
Fri Apr 3 08:55:10 UTC 2020


http://cr.openjdk.java.net/~roland/8241900/webrev.00/

When a loop is unswitched, the now redundant test in the loop bodies is
changed so it always fails or succeeds. Data nodes that are control
dependent on the test become control dependent on the dominating
control.

In the test case:

1) the loop is unswitched once. The test that's hoisted is:
if (o3 != null) {

2) the loop is unswitched a second time. This time, the hoisted test is:
if (o != null) {

3) that test has a control dependent CastPP. That CastPP becomes
dependent on the dominating test:
if (o2 == null) {
that test never fails so it's compiled as a test + uncommon trap

4) partial peeling is applied

The chain of tests is now:

if (array[1] != null) { // hoisted o3 != null by unswitching
  if (objectField != null) { // hoisted o != null by unswitching
    if (array[1] != null) { // peeled o2 == null
      // CastPP on objectField is here

5) because the 3rd test is identical to the first one this becomes:

if (array[1] != null) { // hoisted o3 != null by unswitching
  // CastPP on objectField is here
  if (objectField != null) { // hoisted o != null by unswitching

So the CastPP bypasses the null check on its input and so a dependent
load can flow above the null check.

The fix I propose is to keep the dependence on the hoisted test on loop
unswitching by using dominated_by() instead of short_circuit_if(). This
way on step 2) 3) above, the CastPP is made dependent on the hoisted
test so reordering of the CastPP with its null check can't happen.

Roland.



More information about the hotspot-compiler-dev mailing list