Skip to content

8355574: Fatal error in abort_verify_int_in_range due to Invalid CastII #25284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions src/hotspot/share/opto/arraycopynode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include "gc/shared/gc_globals.hpp"
#include "opto/arraycopynode.hpp"
#include "opto/graphKit.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/macros.hpp"
#include "utilities/powerOfTwo.hpp"

const TypeFunc* ArrayCopyNode::_arraycopy_type_Type = nullptr;
Expand Down Expand Up @@ -770,15 +768,17 @@ bool ArrayCopyNode::modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues
return false;
}

// As an optimization, choose optimum vector size for copy length known at compile time.
int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, int const_len) {
int lane_count = ArrayOperationPartialInlineSize/type2aelembytes(type);
if (const_len > 0) {
int size_in_bytes = const_len * type2aelembytes(type);
if (size_in_bytes <= 16)
lane_count = 16/type2aelembytes(type);
else if (size_in_bytes > 16 && size_in_bytes <= 32)
lane_count = 32/type2aelembytes(type);
}
return lane_count;
// As an optimization, choose the optimal vector size for bounded copy length
int ArrayCopyNode::get_partial_inline_vector_lane_count(BasicType type, jlong max_len) {
assert(max_len > 0, JLONG_FORMAT, max_len);
// We only care whether max_size_in_bytes is not larger than 32, we also want to avoid
// multiplication overflow, so clamp max_len to [0, 64]
int max_size_in_bytes = MIN2<jlong>(max_len, 64) * type2aelembytes(type);
if (ArrayOperationPartialInlineSize > 16 && max_size_in_bytes <= 16) {
return 16 / type2aelembytes(type);
} else if (ArrayOperationPartialInlineSize > 32 && max_size_in_bytes <= 32) {
return 32 / type2aelembytes(type);
} else {
return ArrayOperationPartialInlineSize / type2aelembytes(type);
}
}
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/arraycopynode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class ArrayCopyNode : public CallNode {

static bool may_modify(const TypeOopPtr* t_oop, MemBarNode* mb, PhaseValues* phase, ArrayCopyNode*& ac);

static int get_partial_inline_vector_lane_count(BasicType type, int const_len);
static int get_partial_inline_vector_lane_count(BasicType type, jlong max_len);

bool modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseValues* phase, bool must_modify) const;

Expand Down
51 changes: 22 additions & 29 deletions src/hotspot/share/opto/macroArrayCopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,53 +204,46 @@ void PhaseMacroExpand::generate_limit_guard(Node** ctrl, Node* offset, Node* sub
void PhaseMacroExpand::generate_partial_inlining_block(Node** ctrl, MergeMemNode** mem, const TypePtr* adr_type,
RegionNode** exit_block, Node** result_memory, Node* length,
Node* src_start, Node* dst_start, BasicType type) {
const TypePtr *src_adr_type = _igvn.type(src_start)->isa_ptr();
Node* inline_block = nullptr;
Node* stub_block = nullptr;

int const_len = -1;
const TypeInt* lty = nullptr;
uint shift = exact_log2(type2aelembytes(type));
if (length->Opcode() == Op_ConvI2L) {
lty = _igvn.type(length->in(1))->isa_int();
} else {
lty = _igvn.type(length)->isa_int();
}
if (lty && lty->is_con()) {
const_len = lty->get_con() << shift;
int inline_limit = ArrayOperationPartialInlineSize / type2aelembytes(type);

const TypeLong* length_type = _igvn.type(length)->isa_long();
if (length_type == nullptr) {
assert(_igvn.type(length) == Type::TOP, "");
return;
} else if (length_type->_hi <= 0) {
// Nothing to copy
return;
} else if (length_type->_lo > inline_limit) {
// Cannot inline
return;
}

// Return if copy length is greater than partial inline size limit or
// target does not supports masked load/stores.
int lane_count = ArrayCopyNode::get_partial_inline_vector_lane_count(type, const_len);
if ( const_len > ArrayOperationPartialInlineSize ||
!Matcher::match_rule_supported_vector(Op_LoadVectorMasked, lane_count, type) ||
// Return if the target does not supports masked load/stores.
int lane_count = ArrayCopyNode::get_partial_inline_vector_lane_count(type, length_type->_hi);
if (!Matcher::match_rule_supported_vector(Op_LoadVectorMasked, lane_count, type) ||
!Matcher::match_rule_supported_vector(Op_StoreVectorMasked, lane_count, type) ||
!Matcher::match_rule_supported_vector(Op_VectorMaskGen, lane_count, type)) {
return;
}

int inline_limit = ArrayOperationPartialInlineSize / type2aelembytes(type);
Node* casted_length = new CastLLNode(*ctrl, length, TypeLong::make(0, inline_limit, Type::WidenMin));
transform_later(casted_length);
Node* copy_bytes = new LShiftXNode(length, intcon(shift));
transform_later(copy_bytes);

Node* cmp_le = new CmpULNode(copy_bytes, longcon(ArrayOperationPartialInlineSize));
Node* cmp_le = new CmpULNode(length, longcon(inline_limit));
transform_later(cmp_le);
Node* bol_le = new BoolNode(cmp_le, BoolTest::le);
transform_later(bol_le);
inline_block = generate_guard(ctrl, bol_le, nullptr, PROB_FAIR);
stub_block = *ctrl;
Node* inline_block = generate_guard(ctrl, bol_le, nullptr, PROB_FAIR);
Node* stub_block = *ctrl;

Node* casted_length = new CastLLNode(inline_block, length, TypeLong::make(0, inline_limit, Type::WidenMin), ConstraintCastNode::RegularDependency);
transform_later(casted_length);
Node* mask_gen = VectorMaskGenNode::make(casted_length, type);
transform_later(mask_gen);

unsigned vec_size = lane_count * type2aelembytes(type);
unsigned vec_size = lane_count * type2aelembytes(type);
if (C->max_vector_size() < vec_size) {
C->set_max_vector_size(vec_size);
}

const TypePtr* src_adr_type = _igvn.type(src_start)->isa_ptr();
const TypeVect * vt = TypeVect::make(type, lane_count);
Node* mm = (*mem)->memory_at(C->get_alias_index(src_adr_type));
Node* masked_load = new LoadVectorMaskedNode(inline_block, mm, src_start,
Expand Down
2 changes: 0 additions & 2 deletions test/hotspot/jtreg/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ compiler/interpreter/Test6833129.java 8335266 generic-i586
compiler/ciReplay/TestInliningProtectionDomain.java 8349191 generic-all
compiler/ciReplay/TestIncrementalInlining.java 8349191 generic-all

compiler/c2/TestVerifyConstraintCasts.java 8355574 generic-all

#############################################################################

# :hotspot_gc
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. 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
Expand All @@ -26,7 +26,7 @@

/**
* @test
* @bug 8251871 8285301
* @bug 8251871 8285301 8355574
* @summary Optimize arrayCopy using AVX-512 masked instructions.
*
* @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch -XX:+IgnoreUnrecognizedVMOptions
Expand All @@ -38,6 +38,9 @@
* @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch -XX:+IgnoreUnrecognizedVMOptions
* -XX:UseAVX=3 -XX:+UnlockDiagnosticVMOptions -XX:ArrayOperationPartialInlineSize=32 -XX:+UnlockDiagnosticVMOptions -XX:MaxVectorSize=32 -XX:+UnlockDiagnosticVMOption
* compiler.arraycopy.TestArrayCopyConjoint
* @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+StressGCM -XX:VerifyConstraintCasts=2
* -XX:UseAVX=3 -XX:+UnlockDiagnosticVMOptions -XX:ArrayOperationPartialInlineSize=32 -XX:+UnlockDiagnosticVMOptions -XX:MaxVectorSize=32 -XX:+UnlockDiagnosticVMOption
* compiler.arraycopy.TestArrayCopyConjoint
* @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch -XX:+IgnoreUnrecognizedVMOptions
* -XX:UseAVX=3 -XX:+UnlockDiagnosticVMOptions -XX:ArrayOperationPartialInlineSize=32 -XX:+UnlockDiagnosticVMOptions -XX:MaxVectorSize=64
* compiler.arraycopy.TestArrayCopyConjoint
Expand Down