8262998: Vector API intrinsincs should not modify IR when bailing out

Reviewed-by: thartmann, vlivanov
This commit is contained in:
Jie Fu 2021-03-05 05:57:30 +00:00
parent 80182f92db
commit d91550efad
2 changed files with 92 additions and 1 deletions
src/hotspot/share/opto
test/hotspot/jtreg/compiler/vectorapi

@ -609,8 +609,12 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
Node* base = argument(3);
Node* offset = ConvL2X(argument(4));
DecoratorSet decorators = C2_UNSAFE_ACCESS;
Node* addr = make_unsafe_address(base, offset, decorators, (is_mask ? T_BOOLEAN : elem_bt), true);
// Save state and restore on bailout
uint old_sp = sp();
SafePointNode* old_map = clone_map();
Node* addr = make_unsafe_address(base, offset, decorators, (is_mask ? T_BOOLEAN : elem_bt), true);
// Can base be NULL? Otherwise, always on-heap access.
bool can_access_non_heap = TypePtr::NULL_PTR->higher_equal(gvn().type(base));
@ -622,6 +626,8 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
// Handle loading masks.
// If there is no consistency between array and vector element types, it must be special byte array case or loading masks
if (arr_type != NULL && !using_byte_array && elem_bt != arr_type->elem()->array_element_basic_type() && !is_mask) {
set_map(old_map);
set_sp(old_sp);
return false;
}
// Since we are using byte array, we need to double check that the byte operations are supported by backend.
@ -634,6 +640,8 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
is_store, is_store ? "store" : "load",
byte_num_elem, type2name(elem_bt));
}
set_map(old_map);
set_sp(old_sp);
return false; // not supported
}
}
@ -644,14 +652,20 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
is_store, is_store ? "store" : "load",
num_elem);
}
set_map(old_map);
set_sp(old_sp);
return false; // not supported
}
if (!is_store) {
if (!arch_supports_vector(Op_LoadVector, num_elem, elem_bt, VecMaskUseLoad)) {
set_map(old_map);
set_sp(old_sp);
return false; // not supported
}
} else {
if (!arch_supports_vector(Op_StoreVector, num_elem, elem_bt, VecMaskUseStore)) {
set_map(old_map);
set_sp(old_sp);
return false; // not supported
}
}
@ -666,6 +680,8 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
if (is_store) {
Node* val = unbox_vector(argument(6), vbox_type, elem_bt, num_elem);
if (val == NULL) {
set_map(old_map);
set_sp(old_sp);
return false; // operand unboxing failed
}
set_all_memory(reset_memory());
@ -702,6 +718,8 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
set_result(box);
}
old_map->destruct(&_gvn);
if (can_access_non_heap) {
insert_mem_bar(Op_MemBarCPUOrder);
}
@ -779,6 +797,11 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
Node* base = argument(4);
Node* offset = ConvL2X(argument(5));
// Save state and restore on bailout
uint old_sp = sp();
SafePointNode* old_map = clone_map();
Node* addr = make_unsafe_address(base, offset, C2_UNSAFE_ACCESS, elem_bt, true);
const TypePtr *addr_type = gvn().type(addr)->isa_ptr();
@ -786,6 +809,8 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
// The array must be consistent with vector type
if (arr_type == NULL || (arr_type != NULL && elem_bt != arr_type->elem()->array_element_basic_type())) {
set_map(old_map);
set_sp(old_sp);
return false;
}
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
@ -794,6 +819,8 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
ciKlass* vbox_idx_klass = vector_idx_klass->const_oop()->as_instance()->java_lang_Class_klass();
if (vbox_idx_klass == NULL) {
set_map(old_map);
set_sp(old_sp);
return false;
}
@ -801,12 +828,16 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
Node* index_vect = unbox_vector(argument(7), vbox_idx_type, T_INT, num_elem);
if (index_vect == NULL) {
set_map(old_map);
set_sp(old_sp);
return false;
}
const TypeVect* vector_type = TypeVect::make(elem_bt, num_elem);
if (is_scatter) {
Node* val = unbox_vector(argument(8), vbox_type, elem_bt, num_elem);
if (val == NULL) {
set_map(old_map);
set_sp(old_sp);
return false; // operand unboxing failed
}
set_all_memory(reset_memory());
@ -820,6 +851,8 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) {
set_result(box);
}
old_map->destruct(&_gvn);
C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
return true;
}

@ -0,0 +1,58 @@
/*
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.vectorapi;
import jdk.incubator.vector.*;
import java.nio.ByteOrder;
/*
* @test
* @bug 8262998
* @summary Vector API intrinsincs should not modify IR when bailing out
* @modules jdk.incubator.vector
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:UseAVX=1
* -XX:-TieredCompilation compiler.vectorapi.TestIntrinsicBailOut
*/
public class TestIntrinsicBailOut {
static final VectorSpecies<Double> SPECIES256 = DoubleVector.SPECIES_256;
static byte[] a = new byte[512];
static byte[] r = new byte[512];
static void test() {
DoubleVector av = DoubleVector.fromByteArray(SPECIES256, a, 0, ByteOrder.BIG_ENDIAN);
av.intoByteArray(r, 0, ByteOrder.BIG_ENDIAN);
DoubleVector bv = DoubleVector.fromByteArray(SPECIES256, a, 32, ByteOrder.LITTLE_ENDIAN);
bv.intoByteArray(r, 32, ByteOrder.LITTLE_ENDIAN);
}
public static void main(String[] args) {
for (int i = 0; i < 15000; i++) {
test();
}
System.out.println(r[0] + r[32]);
}
}