8202949: C2: assert(false) failed: Bad graph detected in build_loop_late
Fixed trip count computation for counted loop with negative stride to prevent over-unrolling. Reviewed-by: roland
This commit is contained in:
parent
313a255558
commit
2d00538d92
@ -116,9 +116,11 @@ void IdealLoopTree::compute_trip_count(PhaseIdealLoop* phase) {
|
||||
if (init_n != NULL && limit_n != NULL) {
|
||||
// Use longs to avoid integer overflow.
|
||||
int stride_con = cl->stride_con();
|
||||
jlong init_con = phase->_igvn.type(init_n)->is_int()->_lo;
|
||||
jlong limit_con = phase->_igvn.type(limit_n)->is_int()->_hi;
|
||||
int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
|
||||
const TypeInt* init_type = phase->_igvn.type(init_n)->is_int();
|
||||
const TypeInt* limit_type = phase->_igvn.type(limit_n)->is_int();
|
||||
jlong init_con = (stride_con > 0) ? init_type->_lo : init_type->_hi;
|
||||
jlong limit_con = (stride_con > 0) ? limit_type->_hi : limit_type->_lo;
|
||||
int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
|
||||
jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
|
||||
if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
|
||||
if (init_n->is_Con() && limit_n->is_Con()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, 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
|
||||
@ -23,20 +23,19 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8159016
|
||||
* @bug 8159016 8202949
|
||||
* @summary Tests correct dominator information after over-unrolling a loop.
|
||||
* @requires vm.gc == "Parallel" | vm.gc == "null"
|
||||
*
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation
|
||||
* -XX:-UseG1GC -XX:+UseParallelGC
|
||||
* compiler.loopopts.TestOverunrolling
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
|
||||
* -Xcomp -XX:-TieredCompilation -XX:-UseSwitchProfiling
|
||||
* -XX:-UseG1GC -XX:+UseParallelGC compiler.loopopts.TestOverunrolling
|
||||
*/
|
||||
|
||||
package compiler.loopopts;
|
||||
|
||||
public class TestOverunrolling {
|
||||
|
||||
public static Object test(int arg) {
|
||||
public static Object test1(int arg) {
|
||||
Object arr[] = new Object[3];
|
||||
int lim = (arg & 3);
|
||||
// The pre loop is executed for one iteration, initializing p[0].
|
||||
@ -53,10 +52,40 @@ public class TestOverunrolling {
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static long lFld = 0;
|
||||
public static volatile double dFld = 0;
|
||||
|
||||
public static void test2() {
|
||||
int iArr[] = new int[10];
|
||||
// The inner for-loop is overunrolled because we fail to determine
|
||||
// the constant lower and upper bound (6,8]. After unrolling multiple times,
|
||||
// the range check dependent CastII/ConvI2L emitted for the iArr access become
|
||||
// TOP because index 'j' is out of bounds. As a result, the memory graph is
|
||||
// corrupted with memory consuming nodes still being reachable because the dead
|
||||
// loop is not (yet) removed (Opaque1 nodes are still guarding the bounds).
|
||||
for (int i = 6; i < 10; i++) {
|
||||
for (int j = 8; j > i; j--) {
|
||||
int k = 1;
|
||||
do {
|
||||
iArr[j] = 0;
|
||||
switch (k) {
|
||||
case 1:
|
||||
lFld = 0;
|
||||
break;
|
||||
case 10:
|
||||
dFld = 0;
|
||||
break;
|
||||
}
|
||||
} while (++k < 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
for (int i = 0; i < 42; ++i) {
|
||||
test(i);
|
||||
test1(i);
|
||||
}
|
||||
test2();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user