Skip to content
Permalink
Browse files

8236443: Issues with specializing vector register type for phi operan…

…d with generic operands

Fix special handling for operand resolution of vectorshift and shiftcount nodes. Fix for crash in the resolution algorithm due to non-machine type nodes.

Reviewed-by: vlivanov
  • Loading branch information
Jatin Bhateja
Jatin Bhateja committed Jan 14, 2020
1 parent 1507a1f commit eccf39b29511893c72114a69961011c3d3402a71
@@ -2525,14 +2525,17 @@ void Matcher::do_postselect_cleanup() {
//----------------------------------------------------------------------

// Convert (leg)Vec to (leg)Vec[SDXYZ].
MachOper* Matcher::specialize_vector_operand_helper(MachNode* m, MachOper* original_opnd) {
const Type* t = m->bottom_type();
MachOper* Matcher::specialize_vector_operand_helper(MachNode* m, uint opnd_idx, const Type* t) {
MachOper* original_opnd = m->_opnds[opnd_idx];
uint ideal_reg = t->ideal_reg();
// Handle special cases
// Handle special cases.
if (t->isa_vect()) {
// RShiftCntV/RShiftCntV report wide vector type, but VecS as ideal register (see vectornode.hpp).
if (m->ideal_Opcode() == Op_RShiftCntV || m->ideal_Opcode() == Op_LShiftCntV) {
ideal_reg = TypeVect::VECTS->ideal_reg(); // ideal_reg == Op_VecS
// LShiftCntV/RShiftCntV report wide vector type, but Matcher::vector_shift_count_ideal_reg() as ideal register (see vectornode.hpp).
// Look for shift count use sites as well (at vector shift nodes).
int opc = m->ideal_Opcode();
if ((VectorNode::is_shift_count(opc) && opnd_idx == 0) || // DEF operand of LShiftCntV/RShiftCntV
(VectorNode::is_vector_shift(opc) && opnd_idx == 2)) { // shift operand of a vector shift node
ideal_reg = Matcher::vector_shift_count_ideal_reg(t->is_vect()->length_in_bytes());
}
} else {
// Chain instructions which convert scalar to vector (e.g., vshiftcntimm on x86) don't have vector type.
@@ -2556,22 +2559,23 @@ void Matcher::specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx) {
}

// Compute concrete vector operand for a generic DEF/USE vector operand (of mach node m at index idx).
MachOper* Matcher::specialize_vector_operand(MachNode* m, uint idx) {
assert(Matcher::is_generic_vector(m->_opnds[idx]), "repeated updates");
if (idx == 0) { // DEF
// Use mach node itself to compute vector operand type.
return specialize_vector_operand_helper(m, m->_opnds[0]);
MachOper* Matcher::specialize_vector_operand(MachNode* m, uint opnd_idx) {
assert(Matcher::is_generic_vector(m->_opnds[opnd_idx]), "repeated updates");
Node* def = NULL;
if (opnd_idx == 0) { // DEF
def = m; // use mach node itself to compute vector operand type
} else {
// Use def node to compute operand type.
int base_idx = m->operand_index(idx);
MachNode* in = m->in(base_idx)->as_Mach();
if (in->is_MachTemp() && Matcher::is_generic_vector(in->_opnds[0])) {
specialize_temp_node(in->as_MachTemp(), m, base_idx); // MachTemp node use site
} else if (is_generic_reg2reg_move(in)) {
in = in->in(1)->as_Mach(); // skip over generic reg-to-reg moves
int base_idx = m->operand_index(opnd_idx);
def = m->in(base_idx);
if (def->is_Mach()) {
if (def->is_MachTemp() && Matcher::is_generic_vector(def->as_Mach()->_opnds[0])) {
specialize_temp_node(def->as_MachTemp(), m, base_idx); // MachTemp node use site
} else if (is_generic_reg2reg_move(def->as_Mach())) {
def = def->in(1); // skip over generic reg-to-reg moves
}
}
return specialize_vector_operand_helper(in, m->_opnds[idx]);
}
return specialize_vector_operand_helper(m, opnd_idx, def->bottom_type());
}

void Matcher::specialize_mach_node(MachNode* m) {
@@ -516,8 +516,8 @@ class Matcher : public PhaseTransform {
void specialize_generic_vector_operands();
void specialize_mach_node(MachNode* m);
void specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx);
MachOper* specialize_vector_operand(MachNode* m, uint idx);
MachOper* specialize_vector_operand_helper(MachNode* m, MachOper* generic_opnd);
MachOper* specialize_vector_operand(MachNode* m, uint opnd_idx);
MachOper* specialize_vector_operand_helper(MachNode* m, uint opnd_idx, const Type* t);

static MachOper* specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp);

@@ -485,6 +485,38 @@ VectorNode* VectorNode::shift_count(Node* shift, Node* cnt, uint vlen, BasicType
}
}

bool VectorNode::is_vector_shift(int opc) {
assert(opc > _last_machine_leaf && opc < _last_opcode, "invalid opcode");
switch (opc) {
case Op_LShiftVB:
case Op_LShiftVS:
case Op_LShiftVI:
case Op_LShiftVL:
case Op_RShiftVB:
case Op_RShiftVS:
case Op_RShiftVI:
case Op_RShiftVL:
case Op_URShiftVB:
case Op_URShiftVS:
case Op_URShiftVI:
case Op_URShiftVL:
return true;
default:
return false;
}
}

bool VectorNode::is_shift_count(int opc) {
assert(opc > _last_machine_leaf && opc < _last_opcode, "invalid opcode");
switch (opc) {
case Op_RShiftCntV:
case Op_LShiftCntV:
return true;
default:
return false;
}
}

// Return initial Pack node. Additional operands added with add_opd() calls.
PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
const TypeVect* vt = TypeVect::make(bt, vlen);
@@ -74,6 +74,9 @@ class VectorNode : public TypeNode {
static bool is_invariant_vector(Node* n);
// [Start, end) half-open range defining which operands are vectors
static void vector_operands(Node* n, uint* start, uint* end);

static bool is_vector_shift(int opc);
static bool is_shift_count(int opc);
};

//===========================Vector=ALU=Operations=============================

0 comments on commit eccf39b

Please sign in to comment.