[16] RFR(M): 8249607: C2: assert(!had_error) failed: bad dominance

Christian Hagedorn christian.hagedorn at oracle.com
Fri Aug 21 14:28:08 UTC 2020


Hi

Please review the following patch:
https://bugs.openjdk.java.net/browse/JDK-8249607
http://cr.openjdk.java.net/~chagedorn/8249607/webrev.00/

In the testcase, a LoadSNode is cloned in 
PhaseIdealLoop::split_if_with_blocks_post() for each use such that they 
can float out of a loop. To ensure that these loads cannot float back 
into the loop, we pin them by setting their control input [1]. In the 
testcase, all 3 new clones are pinned to a loop exit node that is part 
of an outer strip mined loop (see [2]).

The clones LoadS 901 and 902 have a late control that is outside of the 
strip mined loop 879. But the dominance information is still correct 
after the SplitIf optimization since the inner loop exit node 876 
IfFalse is still on the dominator chains of these late controls.

We later create pre/main/post loops and add additional RegionNodes to 
merge them together. However, we do not consider these LoadSNodes that 
have a control input from 876 IfFalse. When later verifying for each 
node that its early control dominates its latest possible control, we 
fail because we cannot reach 876 IfFalse anymore on a dominator chain 
for the late controls of LoadS 901 and 902 which start further down 
outside of the strip mined loop 879.

We have two options to fix this. We could either update the wrong 
control inputs from 876 IfFalse during the creation/merging of 
pre/main/post loops or directly fix it inside 
split_if_with_blocks_post(). I think it is makes more sense and is also 
easier to directly fix it in split_if_with_blocks_post() where we could 
be less pessimistic when pinning loads.

The fix now checks if late_load_ctrl is a loop exit of a loop that has 
an outer strip mined loop and if it dominates x_ctrl. If that is the 
case, we use the outer loop exit control instead. This also means that 
the loads can completely float out of the outer strip mined loop. 
Applying that to the testcase, we get [3] instead of [2]. LoadS 901 and 
902 are both at the outer strip mined loop exit while 903 LoadS is still 
at the inner loop due to 575 StoreI (x_ctrl is 876 IfFalse and dominates 
the outer strip mined loop exit). The process of creating pre/main/post 
loops will then take care of these control inputs of the LoadSNodes and 
rewires them to the newly created RegionNode such that the dominator 
information is correct again.

I additionally updated the printing output in case of such a dominance 
failure which I think improves the analysis of these problems. It now 
also prints the idom chain of the early node and the actual real LCA of 
early and the wrong LCA together with the idom index:

Real LCA of early 876 (idom[5]) and (wrong) LCA 728 (idom[19]):
  1052	If	===  523  1051  [[ 1035  1053 ]] P=0.999999, C=-1.000000


Thank you!

Best regards,
Christian


[1] 
http://hg.openjdk.java.net/jdk/jdk/file/1c332a041243/src/hotspot/share/opto/loopopts.cpp#l1456
[2] 
https://bugs.openjdk.java.net/secure/attachment/89911/pinned_at_inner_loop_exit.png
[3] 
https://bugs.openjdk.java.net/secure/attachment/89912/pinned_at_outer_strip_mined_loop_exit.png


More information about the hotspot-compiler-dev mailing list