--- old/src/hotspot/share/opto/loopopts.cpp 2018-12-07 00:32:38.706459400 -0800 +++ new/src/hotspot/share/opto/loopopts.cpp 2018-12-07 00:32:38.123065900 -0800 @@ -493,6 +493,42 @@ return NULL; } +Node *PhaseIdealLoop::convert_add_to_muladd(Node* n) { + Node * nn = NULL; + Node * in1 = n->in(1); + Node * in2 = n->in(2); + if (in1->Opcode() == Op_MulI && in2->Opcode() == Op_MulI) { + if (Matcher::match_rule_supported(Op_MulAddS2I) && + Matcher::match_rule_supported(Op_MulAddVS2VI)) { + Node* mul_in1 = in1->in(1); + Node* mul_in2 = in1->in(2); + Node* mul_in3 = in2->in(1); + Node* mul_in4 = in2->in(2); + + if (mul_in1->Opcode() == Op_LoadS && + mul_in2->Opcode() == Op_LoadS && + mul_in3->Opcode() == Op_LoadS && + mul_in4->Opcode() == Op_LoadS) { + Node* adr1 = mul_in1->in(MemNode::Address); + Node* adr2 = mul_in2->in(MemNode::Address); + Node* adr3 = mul_in3->in(MemNode::Address); + Node* adr4 = mul_in4->in(MemNode::Address); + + if (adr1->is_AddP() && adr2->is_AddP() && adr3->is_AddP() && adr4->is_AddP()) { + if ((adr1->in(AddPNode::Base) == adr3->in(AddPNode::Base)) && + (adr2->in(AddPNode::Base) == adr4->in(AddPNode::Base))) { + nn = new MulAddS2INode(mul_in1, mul_in2, mul_in3, mul_in4); + register_new_node(nn, get_ctrl(n)); + _igvn.replace_node(n, nn); + return nn; + } + } + } + } + } + return nn; +} + //------------------------------conditional_move------------------------------- // Attempt to replace a Phi with a conditional move. We have some pretty // strict profitability requirements. All Phis at the merge point must @@ -922,6 +958,11 @@ Node *m = remix_address_expressions( n ); if( m ) return m; + if (n_op == Op_AddI) { + Node *nn = convert_add_to_muladd( n ); + if ( nn ) return nn; + } + if (n->is_ConstraintCast()) { Node* dom_cast = n->as_ConstraintCast()->dominating_cast(&_igvn, this); // ConstraintCastNode::dominating_cast() uses node control input to determine domination.