RFR(S): 8240576: JVM crashes after transformation in C2 IdealLoopTree::merge_many_backedges

Yangfei (Felix) felix.yang at huawei.com
Thu Mar 5 08:51:31 UTC 2020


Hi, 

  Please help review this patch fixing a C2 bug. 
  Bug: https://bugs.openjdk.java.net/browse/JDK-8240576 
  Will prepare a webrev adding the test case later.  

  There is an ordinary nested loop in the test case. 
  When entrybci = -1. It has 5 reducible loop.
  Normal control flow looks like:

          +------+
          |0:Root |
          +------+
            |
            |
            v
       +---------+
 <-----  |1:Region1|<-----------------+
       |if(i<100)|<---------+     |
       +---------+       |     |
          |  ^       |     |
          |  |       |      |
          v  |       |     |
      +-----------+      |      |
      |2:if(mF!=0)|    |      |
      +-----------+      |      |
           |         |     |
           |         |     |
           v         |     |
       +---------+       |     | try-catch
       |3:Region2|    |      |
       |if(j<101)|----------+      |
       +---------+              |
          |  ^              |
          |  |              |
          v  |              |
       +---------+              |
       |4:Region3|           |
       |if(k<102)|             |
       +---------+               |
          |  ^               |
          |  |                |
          v  |                |
+-----------------------------+           |
|5:int mI=new Interger(0x1234)|-----+
+-----------------------------+

Current CompileTask:
C2:  13694  832 % !b        Test::testMethod @ 37 (83 bytes)

Problem triggered during the OSR compilation.
It has 3 reducible loop and 1 irreducible loop.
OSR control flow looks like:

                                           +------+
                                           |0:Root|
                                           +---+--+
                                              |
                                              |
                                              v
+-----------------------------+                       +----+----+
|5:int mI=new Interger(0x1234)|    <---------    |4:Region3|
|                             |--------->    |if(k<102)|
+------------+----------------+                      +--+--+---+
             |                              |  ^
             |                              |  |
             |                              v  |
             |                           +---------+
             |                           |3:Region2|<-----------+
             |  try-catch                  |if(j<101)|         |
             |                           +---------+          |
             |                                |           |
             |                                |           |
             |                                v           |
             |                           +---------+          |
             +-------------------------->           |1:Region1|------>    |
                                         |if(i<100)|         |
                                         +---------+          |
                                            |  ^          |
                                            |  |          |
                                            v  |          |
                                        +-----------+         |
                                        |2:if(mF!=0)|-----------+
                                        +-----------+

In the first beautify_loops, something went wrong when c2 does merge_many_backedges.

2090   // If I am a shared header (multiple backedges), peel off the many
2091   // backedges into a private merge point and use the merge point as
2092   // the one true backedge.
2093   if( _head->req() > 3) {
2094     // Merge the many backedges into a single backedge but leave
2095     // the hottest backedge as separate edge for the following peel.
2096     merge_many_backedges( phase );
2097     result = true;
2098   }

Subgraph before merge_many_backedges:

|                              |
|                              |
|                              v
|                           +---------+
|  try-catch                 |3:Region2|<-----------+
|                           |if(j<101)|        |
|                           +---------+          |
|                                |           |
|                                |           |
|                                v            |
|                            +---------+         |
+-------------------------->           |1:Region1|  ----->  |
                            |if(i<100)|         |
                            +---------+          |
                               |  ^          |
                               |  |          |
                               v  |          |
                            +-----------+         |
                            |2:if(mF!=0)|-----------+
                            +-----------+


Before line 2096, IdealLoopTree looks like:

IdealLoopTree:
N1/N3 irreducible
  N1/N2 reducible


Subgraph after merge_many_backedges:

|                              |
|                              |
|                              v
|                           +--+------+
|  try+catch                 |3:Region2|<-----------+
|                           |if(j<101)|         |
|                           +---------+           |
|                                |             |
|                                |             |
|                                v             |
|                            +----+----+          |
+-------------------------->           |1:Region1|----->     |
                            |if(i<100)|           |
                             ++-------++          |
                             |       ^         |
                             |       |         |
                             |       |         |
                             |     +---------+     |
                             |    |6:Region3|   |
                             |     +---------+     |
                             |       ^         |
                             |       |         |
                             v       |         |
                             +-----------+         |
                             |2:if(mF!=0)| -----------+
                             +-----------+

After line 2096, IdealLoopTree looks like:

IdealLoopTree:
N1/N6 irreducible
   N1/N3 reducible

The overall structure of the loop remains the same, but its irreducible attributes
has been modified incorrectly, which further leads to the vm crash.
Proposed fix prevents doing merge_many_backedges when IdealLoopTree is irreducible.

diff -r 67cc6f3948e3 src/hotspot/share/opto/loopnode.cpp
--- a/src/hotspot/share/opto/loopnode.cpp       Wed Mar 04 15:34:53 2020 -0800
+++ b/src/hotspot/share/opto/loopnode.cpp       Thu Mar 05 09:32:57 2020 +0800
@@ -2091,7 +2091,7 @@
   // If I am a shared header (multiple backedges), peel off the many
   // backedges into a private merge point and use the merge point as
   // the one true backedge.
-  if( _head->req() > 3 ) {
+  if (_head->req() > 3 && !_irreducible) {
     // Merge the many backedges into a single backedge but leave
     // the hottest backedge as separate edge for the following peel.
     merge_many_backedges( phase );

  Tiered 1-3 tested.  Any comment?

Thanks,
Felix


More information about the hotspot-compiler-dev mailing list