Thu, 21 May 2015 16:49:11 +0200
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
src/share/vm/opto/phaseX.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/phaseX.cpp Mon May 25 18:48:06 2015 -0400 1.2 +++ b/src/share/vm/opto/phaseX.cpp Thu May 21 16:49:11 2015 +0200 1.3 @@ -1521,11 +1521,12 @@ 1.4 set_type(n, t); 1.5 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 1.6 Node* m = n->fast_out(i); // Get user 1.7 - if( m->is_Region() ) { // New path to Region? Must recheck Phis too 1.8 + if (m->is_Region()) { // New path to Region? Must recheck Phis too 1.9 for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { 1.10 Node* p = m->fast_out(i2); // Propagate changes to uses 1.11 - if( p->bottom_type() != type(p) ) // If not already bottomed out 1.12 + if (p->bottom_type() != type(p)) { // If not already bottomed out 1.13 worklist.push(p); // Propagate change to user 1.14 + } 1.15 } 1.16 } 1.17 // If we changed the receiver type to a call, we need to revisit 1.18 @@ -1535,12 +1536,31 @@ 1.19 if (m->is_Call()) { 1.20 for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { 1.21 Node* p = m->fast_out(i2); // Propagate changes to uses 1.22 - if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) 1.23 + if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) { 1.24 worklist.push(p->unique_out()); 1.25 + } 1.26 } 1.27 } 1.28 - if( m->bottom_type() != type(m) ) // If not already bottomed out 1.29 + if (m->bottom_type() != type(m)) { // If not already bottomed out 1.30 worklist.push(m); // Propagate change to user 1.31 + } 1.32 + 1.33 + // CmpU nodes can get their type information from two nodes up in the 1.34 + // graph (instead of from the nodes immediately above). Make sure they 1.35 + // are added to the worklist if nodes they depend on are updated, since 1.36 + // they could be missed and get wrong types otherwise. 1.37 + uint m_op = m->Opcode(); 1.38 + if (m_op == Op_AddI || m_op == Op_SubI) { 1.39 + for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { 1.40 + Node* p = m->fast_out(i2); // Propagate changes to uses 1.41 + if (p->Opcode() == Op_CmpU) { 1.42 + // Got a CmpU which might need the new type information from node n. 1.43 + if(p->bottom_type() != type(p)) { // If not already bottomed out 1.44 + worklist.push(p); // Propagate change to user 1.45 + } 1.46 + } 1.47 + } 1.48 + } 1.49 } 1.50 } 1.51 }