--- old/src/hotspot/share/opto/addnode.cpp 2018-12-03 17:07:29.930214200 -0800 +++ new/src/hotspot/share/opto/addnode.cpp 2018-12-03 17:07:29.356413100 -0800 @@ -236,6 +236,40 @@ //============================================================================= + +static Node* convert_add_to_muladd(PhaseGVN *phase, Node* in1, Node* in2) { + // Only convert to this type of node if backend supports and if vectorizer supports it as well. + // The reason vectorizer is also checked is because this transformation is explicitly done + // to make vectorizer analysis easier for forms where type transition happens during operation. + if (Matcher::match_rule_supported(Op_MulAddS2I) && + Matcher::match_rule_supported(Op_MulAddVS2VI)) { + if (in1->Opcode() == Op_MulI && in2->Opcode() == Op_MulI) { + 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))) { + return new MulAddS2INode(mul_in1, mul_in2, mul_in3, mul_in4); + } + } + } + } + } + return NULL; +} + //------------------------------Idealize--------------------------------------- Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* in1 = in(1); @@ -320,6 +354,11 @@ } } + Node* muladd = convert_add_to_muladd(phase, in1, in2); + if (muladd != NULL) { + return muladd; + } + return AddNode::Ideal(phase, can_reshape); }