8257625: C2: Harden input checks in vector intrinsics
Reviewed-by: thartmann
This commit is contained in:
parent
4390f2c8c3
commit
6845fee905
src/hotspot/share/opto
@ -197,12 +197,13 @@ static bool is_klass_initialized(const TypeInstPtr* vec_klass) {
|
||||
// TernaryOperation<VM> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
const TypeInt* opr = gvn().type(argument(0))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInt* opr = gvn().type(argument(0))->isa_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
|
||||
!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -229,6 +230,12 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
int num_elem = vlen->get_con();
|
||||
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
|
||||
int sopc = VectorNode::opcode(opc, elem_bt);
|
||||
if (sopc == 0) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** operation not supported: opc=%s bt=%s", NodeClassNames[opc], type2name(elem_bt));
|
||||
}
|
||||
return false; // operation not supported
|
||||
}
|
||||
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
|
||||
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
|
||||
|
||||
@ -305,14 +312,18 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) {
|
||||
// Sh ShuffleIota(Class<?> E, Class<?> ShuffleClass, Vector.Species<E> s, int length,
|
||||
// int start, int step, int wrap, ShuffleIotaOperation<Sh, E> defaultImpl)
|
||||
bool LibraryCallKit::inline_vector_shuffle_iota() {
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
Node* start = argument(4);
|
||||
const TypeInt* start_val = gvn().type(start)->is_int();
|
||||
Node* step = argument(5);
|
||||
const TypeInt* step_val = gvn().type(step)->is_int();
|
||||
const TypeInt* wrap = gvn().type(argument(6))->is_int();
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
const TypeInt* start_val = gvn().type(argument(4))->isa_int();
|
||||
const TypeInt* step_val = gvn().type(argument(5))->isa_int();
|
||||
const TypeInt* wrap = gvn().type(argument(6))->isa_int();
|
||||
|
||||
Node* start = argument(4);
|
||||
Node* step = argument(5);
|
||||
|
||||
if (shuffle_klass == NULL || vlen == NULL || start_val == NULL || step_val == NULL || wrap == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (!vlen->is_con() || !is_power_of_2(vlen->get_con()) ||
|
||||
shuffle_klass->const_oop() == NULL || !wrap->is_con()) {
|
||||
return false; // not enough info for intrinsification
|
||||
@ -396,12 +407,15 @@ bool LibraryCallKit::inline_vector_shuffle_iota() {
|
||||
// VM shuffleToVector(Class<VM> VecClass, Class<?>E , Class<?> ShuffleClass, Sh s, int length,
|
||||
// ShuffleToVectorOperation<VM,Sh,E> defaultImpl)
|
||||
bool LibraryCallKit::inline_vector_shuffle_to_vector() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->is_instptr();
|
||||
Node* shuffle = argument(3);
|
||||
const TypeInt* vlen = gvn().type(argument(4))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(2))->isa_instptr();
|
||||
Node* shuffle = argument(3);
|
||||
const TypeInt* vlen = gvn().type(argument(4))->isa_int();
|
||||
|
||||
if (vector_klass == NULL || elem_klass == NULL || shuffle_klass == NULL || shuffle->is_top() || vlen == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (!vlen->is_con() || vector_klass->const_oop() == NULL || shuffle_klass->const_oop() == NULL) {
|
||||
return false; // not enough info for intrinsification
|
||||
}
|
||||
@ -451,11 +465,12 @@ bool LibraryCallKit::inline_vector_shuffle_to_vector() {
|
||||
// long bits,
|
||||
// LongFunction<V> defaultImpl)
|
||||
bool LibraryCallKit::inline_vector_broadcast_coerced() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
|
||||
|
||||
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
|
||||
vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -546,11 +561,12 @@ bool LibraryCallKit::inline_vector_broadcast_coerced() {
|
||||
// StoreVectorOperation<C, V> defaultImpl) {
|
||||
|
||||
bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
|
||||
|
||||
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
|
||||
vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -708,12 +724,13 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
|
||||
// StoreVectorOperationWithMap<C, V> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->is_int();
|
||||
const TypeInstPtr* vector_idx_klass = gvn().type(argument(3))->is_instptr();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
|
||||
const TypeInstPtr* vector_idx_klass = gvn().type(argument(3))->isa_instptr();
|
||||
|
||||
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || vector_idx_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (vector_klass == NULL || elem_klass == NULL || vector_idx_klass == NULL || vlen == NULL ||
|
||||
vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || vector_idx_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s viclass=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -812,12 +829,13 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
|
||||
// Function<V,Long> defaultImpl)
|
||||
|
||||
bool LibraryCallKit::inline_vector_reduction() {
|
||||
const TypeInt* opr = gvn().type(argument(0))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInt* opr = gvn().type(argument(0))->isa_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
|
||||
!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -899,12 +917,13 @@ bool LibraryCallKit::inline_vector_reduction() {
|
||||
// BiFunction<V, V, Boolean> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_test() {
|
||||
const TypeInt* cond = gvn().type(argument(0))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInt* cond = gvn().type(argument(0))->isa_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (cond == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL ||
|
||||
!cond->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: cond=%s vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
@ -962,11 +981,14 @@ bool LibraryCallKit::inline_vector_test() {
|
||||
// VectorBlendOp<V,M> defaultImpl) { ...
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_blend() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* mask_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* mask_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (mask_klass == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (mask_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
|
||||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
@ -1032,12 +1054,15 @@ bool LibraryCallKit::inline_vector_blend() {
|
||||
// VectorCompareOp<V,M> defaultImpl) { ...
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_compare() {
|
||||
const TypeInt* cond = gvn().type(argument(0))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* mask_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(3))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(4))->is_int();
|
||||
const TypeInt* cond = gvn().type(argument(0))->isa_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* mask_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(4))->isa_int();
|
||||
|
||||
if (cond == NULL || vector_klass == NULL || mask_klass == NULL || elem_klass == NULL || vlen == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (!cond->is_con() || vector_klass->const_oop() == NULL || mask_klass->const_oop() == NULL ||
|
||||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
@ -1107,11 +1132,14 @@ bool LibraryCallKit::inline_vector_compare() {
|
||||
// VectorSwizzleOp<V, Sh, S, E> defaultImpl) { ...
|
||||
|
||||
bool LibraryCallKit::inline_vector_rearrange() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* shuffle_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (vector_klass == NULL || shuffle_klass == NULL || elem_klass == NULL || vlen == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (shuffle_klass->const_oop() == NULL || vector_klass->const_oop() == NULL ||
|
||||
elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
@ -1182,11 +1210,14 @@ bool LibraryCallKit::inline_vector_rearrange() {
|
||||
// VectorBroadcastIntOp<V> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_broadcast_int() {
|
||||
const TypeInt* opr = gvn().type(argument(0))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->is_int();
|
||||
const TypeInt* opr = gvn().type(argument(0))->isa_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(3))->isa_int();
|
||||
|
||||
if (opr == NULL || vector_klass == NULL || elem_klass == NULL || vlen == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (!opr->is_con() || vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s",
|
||||
@ -1213,7 +1244,19 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
|
||||
BasicType elem_bt = elem_type->basic_type();
|
||||
int num_elem = vlen->get_con();
|
||||
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
|
||||
if (opc == 0 || !VectorNode::is_shift_opcode(opc)) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** operation not supported: op=%d bt=%s", opr->get_con(), type2name(elem_bt));
|
||||
}
|
||||
return false; // operation not supported
|
||||
}
|
||||
int sopc = VectorNode::opcode(opc, elem_bt);
|
||||
if (sopc == 0) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** operation not supported: opc=%s bt=%s", NodeClassNames[opc], type2name(elem_bt));
|
||||
}
|
||||
return false; // operation not supported
|
||||
}
|
||||
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
|
||||
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
|
||||
|
||||
@ -1247,16 +1290,21 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
|
||||
// VectorConvertOp<VOUT, VIN, S> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_convert() {
|
||||
const TypeInt* opr = gvn().type(argument(0))->is_int();
|
||||
const TypeInt* opr = gvn().type(argument(0))->isa_int();
|
||||
|
||||
const TypeInstPtr* vector_klass_from = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInstPtr* elem_klass_from = gvn().type(argument(2))->is_instptr();
|
||||
const TypeInt* vlen_from = gvn().type(argument(3))->is_int();
|
||||
const TypeInstPtr* vector_klass_from = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass_from = gvn().type(argument(2))->isa_instptr();
|
||||
const TypeInt* vlen_from = gvn().type(argument(3))->isa_int();
|
||||
|
||||
const TypeInstPtr* vector_klass_to = gvn().type(argument(4))->is_instptr();
|
||||
const TypeInstPtr* elem_klass_to = gvn().type(argument(5))->is_instptr();
|
||||
const TypeInt* vlen_to = gvn().type(argument(6))->is_int();
|
||||
const TypeInstPtr* vector_klass_to = gvn().type(argument(4))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass_to = gvn().type(argument(5))->isa_instptr();
|
||||
const TypeInt* vlen_to = gvn().type(argument(6))->isa_int();
|
||||
|
||||
if (opr == NULL ||
|
||||
vector_klass_from == NULL || elem_klass_from == NULL || vlen_from == NULL ||
|
||||
vector_klass_to == NULL || elem_klass_to == NULL || vlen_to == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (!opr->is_con() ||
|
||||
vector_klass_from->const_oop() == NULL || elem_klass_from->const_oop() == NULL || !vlen_from->is_con() ||
|
||||
vector_klass_to->const_oop() == NULL || elem_klass_to->const_oop() == NULL || !vlen_to->is_con()) {
|
||||
@ -1431,11 +1479,14 @@ bool LibraryCallKit::inline_vector_convert() {
|
||||
// VecInsertOp<V> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_insert() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->is_int();
|
||||
const TypeInt* idx = gvn().type(argument(4))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
|
||||
const TypeInt* idx = gvn().type(argument(4))->isa_int();
|
||||
|
||||
if (vector_klass == NULL || elem_klass == NULL || vlen == NULL || idx == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s",
|
||||
@ -1521,11 +1572,14 @@ bool LibraryCallKit::inline_vector_insert() {
|
||||
// VecExtractOp<V> defaultImpl) {
|
||||
//
|
||||
bool LibraryCallKit::inline_vector_extract() {
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->is_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->is_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->is_int();
|
||||
const TypeInt* idx = gvn().type(argument(4))->is_int();
|
||||
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
|
||||
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
|
||||
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
|
||||
const TypeInt* idx = gvn().type(argument(4))->isa_int();
|
||||
|
||||
if (vector_klass == NULL || elem_klass == NULL || vlen == NULL || idx == NULL) {
|
||||
return false; // dead code
|
||||
}
|
||||
if (vector_klass->const_oop() == NULL || elem_klass->const_oop() == NULL || !vlen->is_con() || !idx->is_con()) {
|
||||
if (C->print_intrinsics()) {
|
||||
tty->print_cr(" ** missing constant: vclass=%s etype=%s vlen=%s idx=%s",
|
||||
|
@ -43,17 +43,12 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_CHAR:
|
||||
case T_SHORT: return Op_AddVS;
|
||||
case T_INT: return Op_AddVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_AddL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_AddVL;
|
||||
case Op_AddF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_AddVF;
|
||||
case Op_AddD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_AddVD;
|
||||
case Op_AddL: return (bt == T_LONG ? Op_AddVL : 0);
|
||||
case Op_AddF: return (bt == T_FLOAT ? Op_AddVF : 0);
|
||||
case Op_AddD: return (bt == T_DOUBLE ? Op_AddVD : 0);
|
||||
|
||||
case Op_SubI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
@ -61,17 +56,12 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_CHAR:
|
||||
case T_SHORT: return Op_SubVS;
|
||||
case T_INT: return Op_SubVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_SubL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_SubVL;
|
||||
case Op_SubF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_SubVF;
|
||||
case Op_SubD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_SubVD;
|
||||
case Op_SubL: return (bt == T_LONG ? Op_SubVL : 0);
|
||||
case Op_SubF: return (bt == T_FLOAT ? Op_SubVF : 0);
|
||||
case Op_SubD: return (bt == T_DOUBLE ? Op_SubVD : 0);
|
||||
|
||||
case Op_MulI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:return 0;
|
||||
@ -79,35 +69,25 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_CHAR:
|
||||
case T_SHORT: return Op_MulVS;
|
||||
case T_INT: return Op_MulVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_MulL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_MulVL;
|
||||
case Op_MulL: return (bt == T_LONG ? Op_MulVL : 0);
|
||||
case Op_MulF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_MulVF;
|
||||
return (bt == T_FLOAT ? Op_MulVF : 0);
|
||||
case Op_MulD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_MulVD;
|
||||
return (bt == T_DOUBLE ? Op_MulVD : 0);
|
||||
case Op_FmaD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_FmaVD;
|
||||
return (bt == T_DOUBLE ? Op_FmaVD : 0);
|
||||
case Op_FmaF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_FmaVF;
|
||||
return (bt == T_FLOAT ? Op_FmaVF : 0);
|
||||
case Op_CMoveF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_CMoveVF;
|
||||
return (bt == T_FLOAT ? Op_CMoveVF : 0);
|
||||
case Op_CMoveD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_CMoveVD;
|
||||
return (bt == T_DOUBLE ? Op_CMoveVD : 0);
|
||||
case Op_DivF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_DivVF;
|
||||
return (bt == T_FLOAT ? Op_DivVF : 0);
|
||||
case Op_DivD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_DivVD;
|
||||
return (bt == T_DOUBLE ? Op_DivVD : 0);
|
||||
case Op_AbsI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
@ -115,11 +95,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_BYTE: return Op_AbsVB;
|
||||
case T_SHORT: return Op_AbsVS;
|
||||
case T_INT: return Op_AbsVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_AbsL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_AbsVL;
|
||||
return (bt == T_LONG ? Op_AbsVL : 0);
|
||||
case Op_MinI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
@ -127,17 +106,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: return Op_MinV;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_MinL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_MinV;
|
||||
return (bt == T_LONG ? Op_MinV : 0);
|
||||
case Op_MinF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_MinV;
|
||||
return (bt == T_FLOAT ? Op_MinV : 0);
|
||||
case Op_MinD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_MinV;
|
||||
return (bt == T_DOUBLE ? Op_MinV : 0);
|
||||
case Op_MaxI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
@ -145,54 +121,38 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: return Op_MaxV;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_MaxL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_MaxV;
|
||||
return (bt == T_LONG ? Op_MaxV : 0);
|
||||
case Op_MaxF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_MaxV;
|
||||
return (bt == T_FLOAT ? Op_MaxV : 0);
|
||||
case Op_MaxD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_MaxV;
|
||||
return (bt == T_DOUBLE ? Op_MaxV : 0);
|
||||
case Op_AbsF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_AbsVF;
|
||||
return (bt == T_FLOAT ? Op_AbsVF : 0);
|
||||
case Op_AbsD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_AbsVD;
|
||||
return (bt == T_DOUBLE ? Op_AbsVD : 0);
|
||||
case Op_NegI:
|
||||
assert(bt == T_INT, "must be");
|
||||
return Op_NegVI;
|
||||
return (bt == T_INT ? Op_NegVI : 0);
|
||||
case Op_NegF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_NegVF;
|
||||
return (bt == T_FLOAT ? Op_NegVF : 0);
|
||||
case Op_NegD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_NegVD;
|
||||
return (bt == T_DOUBLE ? Op_NegVD : 0);
|
||||
case Op_RoundDoubleMode:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_RoundDoubleModeV;
|
||||
return (bt == T_DOUBLE ? Op_RoundDoubleModeV : 0);
|
||||
case Op_RotateLeft:
|
||||
assert(bt == T_LONG || bt == T_INT, "must be");
|
||||
return Op_RotateLeftV;
|
||||
return (bt == T_LONG || bt == T_INT ? Op_RotateLeftV : 0);
|
||||
case Op_RotateRight:
|
||||
assert(bt == T_LONG || bt == T_INT, "must be");
|
||||
return Op_RotateRightV;
|
||||
return (bt == T_LONG || bt == T_INT ? Op_RotateRightV : 0);
|
||||
case Op_SqrtF:
|
||||
assert(bt == T_FLOAT, "must be");
|
||||
return Op_SqrtVF;
|
||||
return (bt == T_FLOAT ? Op_SqrtVF : 0);
|
||||
case Op_SqrtD:
|
||||
assert(bt == T_DOUBLE, "must be");
|
||||
return Op_SqrtVD;
|
||||
return (bt == T_DOUBLE ? Op_SqrtVD : 0);
|
||||
case Op_PopCountI:
|
||||
if (bt == T_INT) {
|
||||
return Op_PopCountVI;
|
||||
}
|
||||
// Unimplemented for subword types since bit count changes
|
||||
// depending on size of lane (and sign bit).
|
||||
return 0;
|
||||
return (bt == T_INT ? Op_PopCountVI : 0);
|
||||
case Op_LShiftI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
@ -200,11 +160,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_CHAR:
|
||||
case T_SHORT: return Op_LShiftVS;
|
||||
case T_INT: return Op_LShiftVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_LShiftL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_LShiftVL;
|
||||
return (bt == T_LONG ? Op_LShiftVL : 0);
|
||||
case Op_RShiftI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value
|
||||
@ -212,17 +171,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
case T_BYTE: return Op_RShiftVB;
|
||||
case T_SHORT: return Op_RShiftVS;
|
||||
case T_INT: return Op_RShiftVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_RShiftL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_RShiftVL;
|
||||
return (bt == T_LONG ? Op_RShiftVL : 0);
|
||||
case Op_URShiftB:
|
||||
assert(bt == T_BYTE, "must be");
|
||||
return Op_URShiftVB;
|
||||
return (bt == T_BYTE ? Op_URShiftVB : 0);
|
||||
case Op_URShiftS:
|
||||
assert(bt == T_SHORT, "must be");
|
||||
return Op_URShiftVS;
|
||||
return (bt == T_SHORT ? Op_URShiftVS : 0);
|
||||
case Op_URShiftI:
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:return Op_URShiftVB;
|
||||
@ -234,11 +190,10 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
||||
// a short value into int value with sign
|
||||
// extension before a shift.
|
||||
case T_INT: return Op_URShiftVI;
|
||||
default: ShouldNotReachHere(); return 0;
|
||||
default: return 0;
|
||||
}
|
||||
case Op_URShiftL:
|
||||
assert(bt == T_LONG, "must be");
|
||||
return Op_URShiftVL;
|
||||
return (bt == T_LONG ? Op_URShiftVL : 0);
|
||||
case Op_AndI:
|
||||
case Op_AndL:
|
||||
return Op_AndV;
|
||||
@ -372,12 +327,14 @@ bool VectorNode::is_vector_rotate_supported(int vopc, uint vlen, BasicType bt) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorNode::is_shift(Node* n) {
|
||||
switch (n->Opcode()) {
|
||||
bool VectorNode::is_shift_opcode(int opc) {
|
||||
switch (opc) {
|
||||
case Op_LShiftI:
|
||||
case Op_LShiftL:
|
||||
case Op_RShiftI:
|
||||
case Op_RShiftL:
|
||||
case Op_URShiftB:
|
||||
case Op_URShiftS:
|
||||
case Op_URShiftI:
|
||||
case Op_URShiftL:
|
||||
return true;
|
||||
@ -386,6 +343,10 @@ bool VectorNode::is_shift(Node* n) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorNode::is_shift(Node* n) {
|
||||
return is_shift_opcode(n->Opcode());
|
||||
}
|
||||
|
||||
bool VectorNode::is_vshift_cnt(Node* n) {
|
||||
switch (n->Opcode()) {
|
||||
case Op_LShiftCntV:
|
||||
|
@ -75,6 +75,8 @@ class VectorNode : public TypeNode {
|
||||
static VectorNode* make(int opc, Node* n1, Node* n2, Node* n3, uint vlen, BasicType bt);
|
||||
static VectorNode* make(int vopc, Node* n1, Node* n2, Node* n3, const TypeVect* vt);
|
||||
|
||||
static bool is_shift_opcode(int opc);
|
||||
|
||||
static int opcode(int opc, BasicType bt);
|
||||
static int replicate_opcode(BasicType bt);
|
||||
static bool implemented(int opc, uint vlen, BasicType bt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user