8288883: C2: assert(allow_address || t != T_ADDRESS) failed after JDK-8283091

Reviewed-by: kvn, mdoerr
This commit is contained in:
Fei Gao 2022-07-18 05:54:51 +00:00 committed by Ningsheng Jian
parent bc7a1ea249
commit 87340fd540
5 changed files with 106 additions and 26 deletions

View File

@ -1449,6 +1449,12 @@ void SuperWord::extend_packlist() {
//------------------------------adjust_alignment_for_type_conversion---------------------------------
// Adjust the target alignment if conversion between different data size exists in def-use nodes.
int SuperWord::adjust_alignment_for_type_conversion(Node* s, Node* t, int align) {
// Do not use superword for non-primitives
BasicType bt1 = velt_basic_type(s);
BasicType bt2 = velt_basic_type(t);
if (!is_java_primitive(bt1) || !is_java_primitive(bt2)) {
return align;
}
if (longer_type_for_conversion(s) != T_ILLEGAL ||
longer_type_for_conversion(t) != T_ILLEGAL) {
align = align / data_size(s) * data_size(t);
@ -3413,32 +3419,23 @@ void SuperWord::compute_max_depth() {
}
BasicType SuperWord::longer_type_for_conversion(Node* n) {
int opcode = n->Opcode();
switch (opcode) {
case Op_ConvD2I:
case Op_ConvI2D:
case Op_ConvF2D:
case Op_ConvD2F: return T_DOUBLE;
case Op_ConvF2L:
case Op_ConvL2F:
case Op_ConvL2I:
case Op_ConvI2L: return T_LONG;
case Op_ConvI2F: {
BasicType src_t = velt_basic_type(n->in(1));
if (src_t == T_BYTE || src_t == T_SHORT) {
return T_FLOAT;
}
return T_ILLEGAL;
}
case Op_ConvF2I: {
BasicType dst_t = velt_basic_type(n);
if (dst_t == T_BYTE || dst_t == T_SHORT) {
return T_FLOAT;
}
return T_ILLEGAL;
}
if (!VectorNode::is_convert_opcode(n->Opcode()) ||
!in_bb(n->in(1))) {
return T_ILLEGAL;
}
return T_ILLEGAL;
assert(in_bb(n), "must be in the bb");
BasicType src_t = velt_basic_type(n->in(1));
BasicType dst_t = velt_basic_type(n);
// Do not use superword for non-primitives.
// Superword does not support casting involving unsigned types.
if (!is_java_primitive(src_t) || is_unsigned_subword_type(src_t) ||
!is_java_primitive(dst_t) || is_unsigned_subword_type(dst_t)) {
return T_ILLEGAL;
}
int src_size = type2aelembytes(src_t);
int dst_size = type2aelembytes(dst_t);
return src_size == dst_size ? T_ILLEGAL
: (src_size > dst_size ? src_t : dst_t);
}
int SuperWord::max_vector_size_in_def_use_chain(Node* n) {

View File

@ -572,7 +572,7 @@ class SuperWord : public ResourceObj {
void bb_insert_after(Node* n, int pos);
// Compute max depth for expressions from beginning of block
void compute_max_depth();
// Return the longer type for type-conversion node and return illegal type for other nodes.
// Return the longer type for vectorizable type-conversion node or illegal type for other nodes.
BasicType longer_type_for_conversion(Node* n);
// Find the longest type in def-use chain for packed nodes, and then compute the max vector size.
int max_vector_size_in_def_use_chain(Node* n);

View File

@ -1350,6 +1350,7 @@ int VectorCastNode::opcode(BasicType bt, bool is_signed) {
bool VectorCastNode::implemented(int opc, uint vlen, BasicType src_type, BasicType dst_type) {
if (is_java_primitive(dst_type) &&
is_java_primitive(src_type) &&
(vlen > 1) && is_power_of_2(vlen) &&
VectorNode::vector_size_supported(dst_type, vlen)) {
int vopc = VectorCastNode::opcode(src_type);

View File

@ -738,6 +738,10 @@ inline bool is_signed_subword_type(BasicType t) {
return (t == T_BYTE || t == T_SHORT);
}
inline bool is_unsigned_subword_type(BasicType t) {
return (t == T_BOOLEAN || t == T_CHAR);
}
inline bool is_double_word_type(BasicType t) {
return (t == T_DOUBLE || t == T_LONG);
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, Arm Limited. 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.
*/
/**
* @test
* @bug 8288883
* @summary Tests auto-vectorization of type conversion with unsafe.
* @modules java.base/jdk.internal.misc
* @run main/othervm -Xbatch compiler.loopopts.superword.TestVectorizeTypeConversionWithUnsafe
*/
package compiler.loopopts.superword;
import jdk.internal.misc.Unsafe;
public class TestVectorizeTypeConversionWithUnsafe {
private static final int LENGTH = 1024;
private static final int BUFFER_SIZE = LENGTH * 4;
private static final int WARMUP = 10_000;
private static final Unsafe unsafe;
private static final long address;
private static final long base_offset_ints;
private static int[] srcptrs = new int[LENGTH];
static {
unsafe = Unsafe.getUnsafe();
address = unsafe.allocateMemory(BUFFER_SIZE);
base_offset_ints = unsafe.arrayBaseOffset(int[].class);
}
public static long conv(){
long res = 0;
int ecur;
for (int i = 0; i < LENGTH; i++) {
ecur = srcptrs[i];
res += unsafe.getInt(address + ecur);
}
return res;
}
public static void main(String[] args) {
for (int i = 0; i < WARMUP; i++) {
conv();
}
for (int i = 0; i < LENGTH; i++) {
srcptrs[i] = i * 4;
}
unsafe.copyMemory(srcptrs, base_offset_ints, null, address, BUFFER_SIZE);
long res = conv();
unsafe.freeMemory(address);
if (res != 2095104) {
throw new RuntimeException("Wrong result.");
}
}
}