JDK-8298848 : C2: clone all of (CmpP (LoadKlass (AddP down at split if
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 21
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-12-15
  • Updated: 2023-01-09
  • Resolved: 2023-01-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 21
21 masterFixed
Related Reports
Relates :  
Relates :  
Description
This is related to JDK-8297933 and only triggers with it:

The crash occurs because a (If (Bool (CmpP (LoadKlass ..))))
only has a single projection. It lost the other projection because of
a CheckCastPP that becomes top. Initially the pattern is, in pseudo
code,:

if (obj.klass == some_class) {
obj = CheckCastPP#1(obj);
}

obj itself is a CheckCastPP that's pinned at a dominating if. That
dominating if goes through split through phi. The LoadKlass for the
pseudo code above also has control set to the dominating if being
transformed. This result in:

if (phi1 == some_class) {
obj = CheckCastPP#1(phi2);
}

with phi1 = (Phi (LoadKlass obj) (LoadKlass obj)) and phi2 = (Phi obj obj)
with obj = (CheckCastPP#2 obj')

PhiNode::Ideal() transforms phi2 into a new CheckCastPP:
(CheckCastPP#3 obj' obj') with control set to the region right above
the if in the pseudo code above. There happens to be another
CheckCastPP at the same control which casts obj' to a narrower
type. So the new CheckCastPP#3 is replaced by that one (because of
ConstraintCastNode::dominating_cast())and pseudo code becomes:

if (phi1 == some_class) {
obj = CheckCastPP#1(CheckCastPP#4(obj'));
}

and then:

if (phi1 == some_class) {
obj = top;
}

because the types of the 2 CheckCastPPs conflict. That would be ok if:

phi1 == some_class

would constant fold. It would if the test was:

if (CheckCastPP#4(obj').klass == some_klass) {

but because of split if, the (CmpP (LoadKlass ..)) and the
CheckCastPP#1 ended up with 2 different object inputs that then were
transformed differently. The fix I propose is to have split if clone the entire:

(Bool (CmpP (LoadKlass (AddP ..))))

down the same way (Bool (CmpP ..)) is cloned down. After split if, the
pseudo code becomes:

if (phi.klass == some_class) {
obj = CheckCastPP#1(phi);
}

The bug can't occur because the CheckCastPP and (CmpP (LoadKlass ..))
operate on the same phi input. The change in split_if.cpp implements
that.


Comments
Changeset: 87238470 Author: Roland Westrelin <roland@openjdk.org> Date: 2023-01-05 09:33:14 +0000 URL: https://git.openjdk.org/jdk/commit/872384707e89d03ede655aad16f360dc94f10152
05-01-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/11689 Date: 2022-12-15 10:53:37 +0000
15-12-2022

ILW = Segfault in split if but only happens with new code added by JDK-8297933 (not in mainline, yet), never observed without JDK-8297933, -XX:-SplitIfBlocks = MLM = P4
15-12-2022