8325520: Vector loads and stores with indices and masks incorrectly compiled
Reviewed-by: epeter, thartmann
This commit is contained in:
parent
c099f14f07
commit
0c934ff4e2
@ -3516,7 +3516,10 @@ Node* StoreNode::Identity(PhaseGVN* phase) {
|
||||
val->in(MemNode::Address)->eqv_uncast(adr) &&
|
||||
val->in(MemNode::Memory )->eqv_uncast(mem) &&
|
||||
val->as_Load()->store_Opcode() == Opcode()) {
|
||||
result = mem;
|
||||
// Ensure vector type is the same
|
||||
if (!is_StoreVector() || as_StoreVector()->vect_type() == mem->as_LoadVector()->vect_type()) {
|
||||
result = mem;
|
||||
}
|
||||
}
|
||||
|
||||
// Two stores in a row of the same value?
|
||||
@ -3525,7 +3528,24 @@ Node* StoreNode::Identity(PhaseGVN* phase) {
|
||||
mem->in(MemNode::Address)->eqv_uncast(adr) &&
|
||||
mem->in(MemNode::ValueIn)->eqv_uncast(val) &&
|
||||
mem->Opcode() == Opcode()) {
|
||||
result = mem;
|
||||
if (!is_StoreVector()) {
|
||||
result = mem;
|
||||
} else {
|
||||
const StoreVectorNode* store_vector = as_StoreVector();
|
||||
const StoreVectorNode* mem_vector = mem->as_StoreVector();
|
||||
const Node* store_indices = store_vector->indices();
|
||||
const Node* mem_indices = mem_vector->indices();
|
||||
const Node* store_mask = store_vector->mask();
|
||||
const Node* mem_mask = mem_vector->mask();
|
||||
// Ensure types, indices, and masks match
|
||||
if (store_vector->vect_type() == mem_vector->vect_type() &&
|
||||
((store_indices == nullptr) == (mem_indices == nullptr) &&
|
||||
(store_indices == nullptr || store_indices->eqv_uncast(mem_indices))) &&
|
||||
((store_mask == nullptr) == (mem_mask == nullptr) &&
|
||||
(store_mask == nullptr || store_mask->eqv_uncast(mem_mask)))) {
|
||||
result = mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store of zero anywhere into a freshly-allocated object?
|
||||
|
@ -180,8 +180,10 @@ class LoadVectorNode;
|
||||
class LoadVectorMaskedNode;
|
||||
class StoreVectorMaskedNode;
|
||||
class LoadVectorGatherNode;
|
||||
class LoadVectorGatherMaskedNode;
|
||||
class StoreVectorNode;
|
||||
class StoreVectorScatterNode;
|
||||
class StoreVectorScatterMaskedNode;
|
||||
class VerifyVectorAlignmentNode;
|
||||
class VectorMaskCmpNode;
|
||||
class VectorUnboxNode;
|
||||
@ -996,8 +998,12 @@ public:
|
||||
DEFINE_CLASS_QUERY(CompressM)
|
||||
DEFINE_CLASS_QUERY(LoadVector)
|
||||
DEFINE_CLASS_QUERY(LoadVectorGather)
|
||||
DEFINE_CLASS_QUERY(LoadVectorMasked)
|
||||
DEFINE_CLASS_QUERY(LoadVectorGatherMasked)
|
||||
DEFINE_CLASS_QUERY(StoreVector)
|
||||
DEFINE_CLASS_QUERY(StoreVectorScatter)
|
||||
DEFINE_CLASS_QUERY(StoreVectorMasked)
|
||||
DEFINE_CLASS_QUERY(StoreVectorScatterMasked)
|
||||
DEFINE_CLASS_QUERY(ShiftV)
|
||||
DEFINE_CLASS_QUERY(Unlock)
|
||||
|
||||
|
@ -910,6 +910,10 @@ class LoadVectorGatherNode : public LoadVectorNode {
|
||||
((is_subword_type(vect_type()->element_basic_type())) &&
|
||||
idx == MemNode::ValueIn + 1);
|
||||
}
|
||||
virtual int store_Opcode() const {
|
||||
// Ensure it is different from any store opcode to avoid folding when indices are used
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------StoreVectorNode--------------------------------
|
||||
@ -942,6 +946,8 @@ class StoreVectorNode : public StoreNode {
|
||||
|
||||
// Needed for proper cloning.
|
||||
virtual uint size_of() const { return sizeof(*this); }
|
||||
virtual Node* mask() const { return nullptr; }
|
||||
virtual Node* indices() const { return nullptr; }
|
||||
|
||||
#ifdef ASSERT
|
||||
// When AlignVector is enabled, SuperWord only creates aligned vector loads and stores.
|
||||
@ -957,6 +963,7 @@ class StoreVectorNode : public StoreNode {
|
||||
|
||||
class StoreVectorScatterNode : public StoreVectorNode {
|
||||
public:
|
||||
enum { Indices = 4 };
|
||||
StoreVectorScatterNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices)
|
||||
: StoreVectorNode(c, mem, adr, at, val) {
|
||||
init_class_id(Class_StoreVectorScatter);
|
||||
@ -968,12 +975,14 @@ class StoreVectorNode : public StoreNode {
|
||||
virtual uint match_edge(uint idx) const { return idx == MemNode::Address ||
|
||||
idx == MemNode::ValueIn ||
|
||||
idx == MemNode::ValueIn + 1; }
|
||||
virtual Node* indices() const { return in(Indices); }
|
||||
};
|
||||
|
||||
//------------------------------StoreVectorMaskedNode--------------------------------
|
||||
// Store Vector to memory under the influence of a predicate register(mask).
|
||||
class StoreVectorMaskedNode : public StoreVectorNode {
|
||||
public:
|
||||
enum { Mask = 4 };
|
||||
StoreVectorMaskedNode(Node* c, Node* mem, Node* dst, Node* src, const TypePtr* at, Node* mask)
|
||||
: StoreVectorNode(c, mem, dst, at, src) {
|
||||
init_class_id(Class_StoreVectorMasked);
|
||||
@ -987,6 +996,7 @@ class StoreVectorMaskedNode : public StoreVectorNode {
|
||||
return idx > 1;
|
||||
}
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
virtual Node* mask() const { return in(Mask); }
|
||||
};
|
||||
|
||||
//------------------------------LoadVectorMaskedNode--------------------------------
|
||||
@ -1007,6 +1017,10 @@ class LoadVectorMaskedNode : public LoadVectorNode {
|
||||
return idx > 1;
|
||||
}
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
virtual int store_Opcode() const {
|
||||
// Ensure it is different from any store opcode to avoid folding when a mask is used
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------LoadVectorGatherMaskedNode---------------------------------
|
||||
@ -1030,12 +1044,19 @@ class LoadVectorGatherMaskedNode : public LoadVectorNode {
|
||||
idx == MemNode::ValueIn + 1 ||
|
||||
(is_subword_type(vect_type()->is_vect()->element_basic_type()) &&
|
||||
idx == MemNode::ValueIn + 2); }
|
||||
virtual int store_Opcode() const {
|
||||
// Ensure it is different from any store opcode to avoid folding when indices and mask are used
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------StoreVectorScatterMaskedNode--------------------------------
|
||||
// Store Vector into memory via index map under the influence of a predicate register(mask).
|
||||
class StoreVectorScatterMaskedNode : public StoreVectorNode {
|
||||
public:
|
||||
enum { Indices = 4,
|
||||
Mask
|
||||
};
|
||||
StoreVectorScatterMaskedNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val, Node* indices, Node* mask)
|
||||
: StoreVectorNode(c, mem, adr, at, val) {
|
||||
init_class_id(Class_StoreVectorScatterMasked);
|
||||
@ -1050,6 +1071,8 @@ class StoreVectorScatterMaskedNode : public StoreVectorNode {
|
||||
idx == MemNode::ValueIn ||
|
||||
idx == MemNode::ValueIn + 1 ||
|
||||
idx == MemNode::ValueIn + 2; }
|
||||
virtual Node* mask() const { return in(Mask); }
|
||||
virtual Node* indices() const { return in(Indices); }
|
||||
};
|
||||
|
||||
// Verify that memory address (adr) is aligned. The mask specifies the
|
||||
|
@ -755,6 +755,11 @@ public class IRNode {
|
||||
beforeMatchingNameRegex(LOAD_VECTOR_GATHER, "LoadVectorGather");
|
||||
}
|
||||
|
||||
public static final String LOAD_VECTOR_MASKED = PREFIX + "LOAD_VECTOR_MASKED" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(LOAD_VECTOR_MASKED, "LoadVectorMasked");
|
||||
}
|
||||
|
||||
public static final String LOAD_VECTOR_GATHER_MASKED = PREFIX + "LOAD_VECTOR_GATHER_MASKED" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(LOAD_VECTOR_GATHER_MASKED, "LoadVectorGatherMasked");
|
||||
@ -1479,6 +1484,11 @@ public class IRNode {
|
||||
beforeMatchingNameRegex(STORE_VECTOR_SCATTER, "StoreVectorScatter");
|
||||
}
|
||||
|
||||
public static final String STORE_VECTOR_MASKED = PREFIX + "STORE_VECTOR_MASKED" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(STORE_VECTOR_MASKED, "StoreVectorMasked");
|
||||
}
|
||||
|
||||
public static final String STORE_VECTOR_SCATTER_MASKED = PREFIX + "STORE_VECTOR_SCATTER_MASKED" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(STORE_VECTOR_SCATTER_MASKED, "StoreVectorScatterMasked");
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user