mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8236443: Issues with specializing vector register type for phi operand 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
This commit is contained in:
parent
b79d75d033
commit
2b9fef7d7b
4 changed files with 60 additions and 21 deletions
|
@ -2525,14 +2525,17 @@ void Matcher::do_postselect_cleanup() {
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
// Convert (leg)Vec to (leg)Vec[SDXYZ].
|
// Convert (leg)Vec to (leg)Vec[SDXYZ].
|
||||||
MachOper* Matcher::specialize_vector_operand_helper(MachNode* m, MachOper* original_opnd) {
|
MachOper* Matcher::specialize_vector_operand_helper(MachNode* m, uint opnd_idx, const Type* t) {
|
||||||
const Type* t = m->bottom_type();
|
MachOper* original_opnd = m->_opnds[opnd_idx];
|
||||||
uint ideal_reg = t->ideal_reg();
|
uint ideal_reg = t->ideal_reg();
|
||||||
// Handle special cases
|
// Handle special cases.
|
||||||
if (t->isa_vect()) {
|
if (t->isa_vect()) {
|
||||||
// RShiftCntV/RShiftCntV report wide vector type, but VecS as ideal register (see vectornode.hpp).
|
// LShiftCntV/RShiftCntV report wide vector type, but Matcher::vector_shift_count_ideal_reg() as ideal register (see vectornode.hpp).
|
||||||
if (m->ideal_Opcode() == Op_RShiftCntV || m->ideal_Opcode() == Op_LShiftCntV) {
|
// Look for shift count use sites as well (at vector shift nodes).
|
||||||
ideal_reg = TypeVect::VECTS->ideal_reg(); // ideal_reg == Op_VecS
|
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 {
|
} else {
|
||||||
// Chain instructions which convert scalar to vector (e.g., vshiftcntimm on x86) don't have vector type.
|
// 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).
|
// 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) {
|
MachOper* Matcher::specialize_vector_operand(MachNode* m, uint opnd_idx) {
|
||||||
assert(Matcher::is_generic_vector(m->_opnds[idx]), "repeated updates");
|
assert(Matcher::is_generic_vector(m->_opnds[opnd_idx]), "repeated updates");
|
||||||
if (idx == 0) { // DEF
|
Node* def = NULL;
|
||||||
// Use mach node itself to compute vector operand type.
|
if (opnd_idx == 0) { // DEF
|
||||||
return specialize_vector_operand_helper(m, m->_opnds[0]);
|
def = m; // use mach node itself to compute vector operand type
|
||||||
} else {
|
} else {
|
||||||
// Use def node to compute operand type.
|
int base_idx = m->operand_index(opnd_idx);
|
||||||
int base_idx = m->operand_index(idx);
|
def = m->in(base_idx);
|
||||||
MachNode* in = m->in(base_idx)->as_Mach();
|
if (def->is_Mach()) {
|
||||||
if (in->is_MachTemp() && Matcher::is_generic_vector(in->_opnds[0])) {
|
if (def->is_MachTemp() && Matcher::is_generic_vector(def->as_Mach()->_opnds[0])) {
|
||||||
specialize_temp_node(in->as_MachTemp(), m, base_idx); // MachTemp node use site
|
specialize_temp_node(def->as_MachTemp(), m, base_idx); // MachTemp node use site
|
||||||
} else if (is_generic_reg2reg_move(in)) {
|
} else if (is_generic_reg2reg_move(def->as_Mach())) {
|
||||||
in = in->in(1)->as_Mach(); // skip over generic reg-to-reg moves
|
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) {
|
void Matcher::specialize_mach_node(MachNode* m) {
|
||||||
|
|
|
@ -516,8 +516,8 @@ public:
|
||||||
void specialize_generic_vector_operands();
|
void specialize_generic_vector_operands();
|
||||||
void specialize_mach_node(MachNode* m);
|
void specialize_mach_node(MachNode* m);
|
||||||
void specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx);
|
void specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx);
|
||||||
MachOper* specialize_vector_operand(MachNode* m, uint idx);
|
MachOper* specialize_vector_operand(MachNode* m, uint opnd_idx);
|
||||||
MachOper* specialize_vector_operand_helper(MachNode* m, MachOper* generic_opnd);
|
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);
|
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.
|
// Return initial Pack node. Additional operands added with add_opd() calls.
|
||||||
PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
|
PackNode* PackNode::make(Node* s, uint vlen, BasicType bt) {
|
||||||
const TypeVect* vt = TypeVect::make(bt, vlen);
|
const TypeVect* vt = TypeVect::make(bt, vlen);
|
||||||
|
|
|
@ -74,6 +74,9 @@ class VectorNode : public TypeNode {
|
||||||
static bool is_invariant_vector(Node* n);
|
static bool is_invariant_vector(Node* n);
|
||||||
// [Start, end) half-open range defining which operands are vectors
|
// [Start, end) half-open range defining which operands are vectors
|
||||||
static void vector_operands(Node* n, uint* start, uint* end);
|
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=============================
|
//===========================Vector=ALU=Operations=============================
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue