From fbba8576c5209c42e2b6938b82886dce1b5696f0 Mon Sep 17 00:00:00 2001 From: aeriksso Date: Thu, 21 May 2015 16:49:11 +0200 Subject: [PATCH] 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 | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/share/vm/opto/phaseX.cpp b/src/share/vm/opto/phaseX.cpp index 758359d7c..348513206 100644 --- a/src/share/vm/opto/phaseX.cpp +++ b/src/share/vm/opto/phaseX.cpp @@ -1521,11 +1521,12 @@ void PhaseCCP::analyze() { 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 @@ void PhaseCCP::analyze() { 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 + } + } + } + } } } } -- GitLab