diff src/share/vm/opto/phaseX.cpp @ 23043:03596ae35800

8060036: C2: CmpU nodes can end up with wrong type information Summary: CmpU needs to be reprocessed by CCP when an AddI/SubI input's input type change Reviewed-by: mcberg, kvn, roland Contributed-by: andreas.eriksson@oracle.com
author aeriksso
date Thu, 21 May 2015 16:49:11 +0200
parents 4c228230f1d6
children dd9cc155639c c1091733abe6
line wrap: on
line diff
--- a/src/share/vm/opto/phaseX.cpp	Mon May 25 18:48:06 2015 -0400
+++ b/src/share/vm/opto/phaseX.cpp	Thu May 21 16:49:11 2015 +0200
@@ -1521,11 +1521,12 @@
       set_type(n, t);
       for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
         Node* m = n->fast_out(i);   // Get user
-        if( m->is_Region() ) {  // New path to Region?  Must recheck Phis too
+        if (m->is_Region()) {  // New path to Region?  Must recheck Phis too
           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
             Node* p = m->fast_out(i2); // Propagate changes to uses
-            if( p->bottom_type() != type(p) ) // If not already bottomed out
+            if (p->bottom_type() != type(p)) { // If not already bottomed out
               worklist.push(p); // Propagate change to user
+            }
           }
         }
         // If we changed the receiver type to a call, we need to revisit
@@ -1535,12 +1536,31 @@
         if (m->is_Call()) {
           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
             Node* p = m->fast_out(i2);  // Propagate changes to uses
-            if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1)
+            if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) {
               worklist.push(p->unique_out());
+            }
           }
         }
-        if( m->bottom_type() != type(m) ) // If not already bottomed out
+        if (m->bottom_type() != type(m)) { // If not already bottomed out
           worklist.push(m);     // Propagate change to user
+        }
+
+        // CmpU nodes can get their type information from two nodes up in the
+        // graph (instead of from the nodes immediately above). Make sure they
+        // are added to the worklist if nodes they depend on are updated, since
+        // they could be missed and get wrong types otherwise.
+        uint m_op = m->Opcode();
+        if (m_op == Op_AddI || m_op == Op_SubI) {
+          for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
+            Node* p = m->fast_out(i2); // Propagate changes to uses
+            if (p->Opcode() == Op_CmpU) {
+              // Got a CmpU which might need the new type information from node n.
+              if(p->bottom_type() != type(p)) { // If not already bottomed out
+                worklist.push(p); // Propagate change to user
+              }
+            }
+          }
+        }
       }
     }
   }