[VectorAPI]maskFromArray Intrinsic failure
Wang Zhuo(Zhuoren)
zhuoren.wz at alibaba-inc.com
Tue Jan 15 16:37:49 UTC 2019
Hi,
I found intrinsics for maskFromArray always failed. Here is a patch to fix this issue.
Benchmarks containing heavy maskFromArray use can benifit from this patch. such as allTrue/anyTrue.
This patch consists of two parts. In the JDK part, since boolean is only one byte, it is not correct to perform left shift ARRAY_SHIFT for array index. I listed only one file in the patch to avoid a long letter, but this modification should be applied to all types including the template file.
return VectorIntrinsics.load(Int128Mask.class, int.class, LENGTH,
- bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
+ bits, ((long) ix) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
bits, ix,
Another part is in hotspot, please check the below patch
diff -r 890e996dfd1a src/hotspot/share/opto/library_call.cpp
--- a/src/hotspot/share/opto/library_call.cpp Mon Jan 07 10:54:21 2019 +0800
+++ b/src/hotspot/share/opto/library_call.cpp Tue Jan 15 23:45:40 2019 +0800
@@ -7069,13 +7069,13 @@
// Now handle special case where load/store happens from/to byte array but element type is not byte.
bool using_byte_array = arr_type != NULL && arr_type->elem()->array_element_basic_type() == T_BYTE && elem_bt != T_BYTE;
-
- // It must be the case that if it is not special byte array case, there is consistency between
- // array and vector element types.
- if (!using_byte_array && arr_type != NULL && elem_bt != arr_type->elem()->array_element_basic_type()) {
+ // Handle loading masks.
+ ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
+ bool is_mask = vbox_klass->is_vectormask();
+ // If there is no consistency between array and vector element types, it must be special byte array case or loading masks
+ if (!using_byte_array && arr_type != NULL && elem_bt != arr_type->elem()->array_element_basic_type() && !is_mask) {
return false;
}
-
// Since we are using byte array, we need to double check that the byte operations are supported by backend.
if (using_byte_array) {
int byte_num_elem = num_elem * type2aelembytes(elem_bt);
@@ -7083,8 +7083,12 @@
return false; // not supported
}
}
-
- ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
+ if (is_mask) {
+ if (!arch_supports_vector(Op_LoadVector, num_elem, T_BOOLEAN, VecMaskUseLoad)) {
+ return false; // not supported
+ }
+ }
+
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
if (is_store) {
@@ -7114,9 +7118,15 @@
const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem);
vload = gvn().transform(new VectorReinterpretNode(vload, vload->bottom_type()->is_vect(), to_vect_type));
} else {
- vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt));
- }
-
+ // Special handle for masks
+ if (is_mask) {
+ vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN));
+ const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem);
+ vload = gvn().transform(new VectorLoadMaskNode(vload, to_vect_type));
+ } else {
+ vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt));
+ }
+ }
Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);
set_vector_result(box);
}
--- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java Mon Jan 07 10:54:21 2019 +0800
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java Tue Jan 15 23:45:40 2019 +0800
@@ -1338,7 +1338,7 @@
Objects.requireNonNull(bits);
ix = VectorIntrinsics.checkIndex(ix, bits.length, LENGTH);
return VectorIntrinsics.load(Int128Mask.class, int.class, LENGTH,
- bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
+ bits, ((long) ix) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
bits, ix,
(c, idx) -> opm(n -> c[idx + n]));
Regards,
Zhuoren
More information about the panama-dev
mailing list