changeset 57668:e27b546887e7

8236443: Issues with specializing vector register type for phi operand with generic operands Summary: 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
author jbhateja
date Tue, 14 Jan 2020 10:55:11 +0530
parents 57f0df0ce2c6
children 9e414f680603
files src/hotspot/share/opto/matcher.cpp src/hotspot/share/opto/matcher.hpp src/hotspot/share/opto/vectornode.cpp src/hotspot/share/opto/vectornode.hpp
diffstat 4 files changed, 60 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/opto/matcher.cpp	Mon Jan 13 18:00:32 2020 -0800
+++ b/src/hotspot/share/opto/matcher.cpp	Tue Jan 14 10:55:11 2020 +0530
@@ -2525,14 +2525,17 @@
 //----------------------------------------------------------------------
 
 // 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 @@
 }
 
 // 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) {
--- a/src/hotspot/share/opto/matcher.hpp	Mon Jan 13 18:00:32 2020 -0800
+++ b/src/hotspot/share/opto/matcher.hpp	Tue Jan 14 10:55:11 2020 +0530
@@ -516,8 +516,8 @@
   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);
 
--- a/src/hotspot/share/opto/vectornode.cpp	Mon Jan 13 18:00:32 2020 -0800
+++ b/src/hotspot/share/opto/vectornode.cpp	Tue Jan 14 10:55:11 2020 +0530
@@ -485,6 +485,38 @@
   }
 }
 
+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);
--- a/src/hotspot/share/opto/vectornode.hpp	Mon Jan 13 18:00:32 2020 -0800
+++ b/src/hotspot/share/opto/vectornode.hpp	Tue Jan 14 10:55:11 2020 +0530
@@ -74,6 +74,9 @@
   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=============================