Skip to content
Permalink
Browse files
8262998: Vector API intrinsincs should not modify IR when bailing out
Reviewed-by: thartmann, vlivanov
  • Loading branch information
DamonFool committed Mar 5, 2021
1 parent 80182f9 commit d91550efad325b4a896b7cad4a8ed2a70405a112
Showing with 92 additions and 1 deletion.
  1. +34 −1 src/hotspot/share/opto/vectorIntrinsics.cpp
  2. +58 −0 test/hotspot/jtreg/compiler/vectorapi/TestIntrinsicBailOut.java
@@ -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,13 +797,20 @@ 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();
const TypeAryPtr* arr_type = addr_type->isa_aryptr();

// 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,19 +819,25 @@ 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;
}

const TypeInstPtr* vbox_idx_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_idx_klass);

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]);
}
}

1 comment on commit d91550e

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on d91550e Mar 5, 2021

Please sign in to comment.