8324121: SIGFPE in PhaseIdealLoop::extract_long_range_checks
Reviewed-by: kvn, chagedorn
This commit is contained in:
parent
0c1b254be9
commit
cb2a671359
@ -792,13 +792,14 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
|
||||
}
|
||||
#endif
|
||||
|
||||
jlong stride_con = head->stride_con();
|
||||
assert(stride_con != 0, "missed some peephole opt");
|
||||
jlong stride_con_long = head->stride_con();
|
||||
assert(stride_con_long != 0, "missed some peephole opt");
|
||||
// We can't iterate for more than max int at a time.
|
||||
if (stride_con != (jint)stride_con) {
|
||||
if (stride_con_long != (jint)stride_con_long || stride_con_long == min_jint) {
|
||||
assert(bt == T_LONG, "only for long loops");
|
||||
return false;
|
||||
}
|
||||
jint stride_con = checked_cast<jint>(stride_con_long);
|
||||
// The number of iterations for the integer count loop: guarantee no
|
||||
// overflow: max_jint - stride_con max. -1 so there's no need for a
|
||||
// loop limit check if the exit test is <= or >=.
|
||||
@ -966,7 +967,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
|
||||
}
|
||||
|
||||
// Clone the iv data nodes as an integer iv
|
||||
Node* int_stride = _igvn.intcon(checked_cast<int>(stride_con));
|
||||
Node* int_stride = _igvn.intcon(stride_con);
|
||||
set_ctrl(int_stride, C->root());
|
||||
Node* inner_phi = new PhiNode(x->in(0), TypeInt::INT);
|
||||
Node* inner_incr = new AddINode(inner_phi, int_stride);
|
||||
@ -1061,7 +1062,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
|
||||
register_new_node(outer_phi, outer_head);
|
||||
}
|
||||
|
||||
transform_long_range_checks(checked_cast<int>(stride_con), range_checks, outer_phi, inner_iters_actual_int,
|
||||
transform_long_range_checks(stride_con, range_checks, outer_phi, inner_iters_actual_int,
|
||||
inner_phi, iv_add, inner_head);
|
||||
// Peel one iteration of the loop and use the safepoint at the end
|
||||
// of the peeled iteration to insert Parse Predicates. If no well
|
||||
@ -1098,7 +1099,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jlong stride_con, int iters_limit, PhiNode* phi,
|
||||
int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jint stride_con, int iters_limit, PhiNode* phi,
|
||||
Node_List& range_checks) {
|
||||
const jlong min_iters = 2;
|
||||
jlong reduced_iters_limit = iters_limit;
|
||||
@ -1114,7 +1115,8 @@ int PhaseIdealLoop::extract_long_range_checks(const IdealLoopTree* loop, jlong s
|
||||
jlong scale = 0;
|
||||
if (loop->is_range_check_if(if_proj, this, T_LONG, phi, range, offset, scale) &&
|
||||
loop->is_invariant(range) && loop->is_invariant(offset) &&
|
||||
original_iters_limit / ABS(scale * stride_con) >= min_iters) {
|
||||
original_iters_limit / ABS(scale) >= min_iters * ABS(stride_con)) {
|
||||
assert(scale == (jint)scale, "scale should be an int");
|
||||
reduced_iters_limit = MIN2(reduced_iters_limit, original_iters_limit/ABS(scale));
|
||||
range_checks.push(c);
|
||||
}
|
||||
|
@ -1710,8 +1710,8 @@ public:
|
||||
LoopNode* create_inner_head(IdealLoopTree* loop, BaseCountedLoopNode* head, IfNode* exit_test);
|
||||
|
||||
|
||||
int extract_long_range_checks(const IdealLoopTree* loop, jlong stride_con, int iters_limit, PhiNode* phi,
|
||||
Node_List &range_checks);
|
||||
int extract_long_range_checks(const IdealLoopTree* loop, jint stride_con, int iters_limit, PhiNode* phi,
|
||||
Node_List &range_checks);
|
||||
|
||||
void transform_long_range_checks(int stride_con, const Node_List &range_checks, Node* outer_phi,
|
||||
Node* inner_iters_actual_int, Node* inner_phi,
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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
|
||||
* 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 8324121
|
||||
* @summary SIGFPE in PhaseIdealLoop::extract_long_range_checks
|
||||
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestLargeScaleInLongRCOverflow::test* -XX:-TieredCompilation TestLargeScaleInLongRCOverflow
|
||||
*
|
||||
*/
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class TestLargeScaleInLongRCOverflow {
|
||||
|
||||
public static void main(String args[]) {
|
||||
Objects.checkIndex(0, 1);
|
||||
try {
|
||||
test1();
|
||||
} catch (java.lang.IndexOutOfBoundsException e) { }
|
||||
try {
|
||||
test2();
|
||||
} catch (java.lang.IndexOutOfBoundsException e) { }
|
||||
}
|
||||
|
||||
// SIGFPE in PhaseIdealLoop::extract_long_range_checks
|
||||
public static void test1() {
|
||||
for (long i = 1; i < 100; i += 2) {
|
||||
Objects.checkIndex(Long.MIN_VALUE * i, 10);
|
||||
}
|
||||
}
|
||||
|
||||
// "assert(static_cast<T1>(result) == thing) failed: must be" in PhaseIdealLoop::transform_long_range_checks
|
||||
public static void test2() {
|
||||
for (long i = 1; i < 100; i += 2) {
|
||||
Objects.checkIndex((Long.MIN_VALUE + 2) * i, 10);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user