--- old/src/share/vm/opto/compile.cpp 2016-04-28 18:30:06.247232952 +0200 +++ new/src/share/vm/opto/compile.cpp 2016-04-28 18:30:02.798247624 +0200 @@ -3263,6 +3263,39 @@ frc._tests.push(iff); break; } + case Op_ConvI2L: { +#ifdef AARCH64 + // Code generation on ARM doesn't need accurate ConvI2L + // types. Widening the type can help remove redundant address + // computations. + n->as_Type()->set_type(TypeLong::INT); + ResourceMark rm; + Node_List wq; + wq.push(n); + for (uint next = 0; next < wq.size(); next++) { + Node *m = wq.at(next); + + for(;;) { + Node* k = m->find_similar(m->Opcode()); + if (k == NULL || + !(k->Opcode() == Op_ConvI2L || + k->Opcode() == Op_LShiftL || + k->Opcode() == Op_AddL || + k->Opcode() == Op_SubL || + k->Opcode() == Op_AddP)) { + break; + } + for (DUIterator_Fast imax, i = k->fast_outs(imax); i < imax; i++) { + Node* u = k->fast_out(i); + assert(!wq.contains(u), "shouldn't process one node several times"); + wq.push(u); + } + k->subsume_by(m, this); + } + } +#endif + break; + } default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); --- old/src/share/vm/opto/node.cpp 2016-04-28 18:30:09.959217157 +0200 +++ new/src/share/vm/opto/node.cpp 2016-04-28 18:30:06.542231697 +0200 @@ -2297,7 +2297,8 @@ if (def && def->outcnt() >= 2) { for (DUIterator_Fast dmax, i = def->fast_outs(dmax); i < dmax; i++) { Node* use = def->fast_out(i); - if (use->Opcode() == opc && + if (use != this && + use->Opcode() == opc && use->req() == req()) { uint j; for (j = 0; j < use->req(); j++) {