8190375: Java Crash in JavaBug.formatPos(I)Ljava/lang/String
Summary: Skip the logic that set the value of the Phi iv if the exit condition is "not equal"
Reviewed-by: thartmann, mdoerr
--- a/src/hotspot/share/opto/cfgnode.cpp Thu Aug 31 10:00:28 2017 +0200
+++ b/src/hotspot/share/opto/cfgnode.cpp Mon Nov 13 14:53:28 2017 -0500
@@ -918,11 +918,18 @@
const TypeInt* stride_t = phase->type(stride)->isa_int();
if (lo != NULL && hi != NULL && stride_t != NULL) { // Dying loops might have TOP here
assert(stride_t->_hi >= stride_t->_lo, "bad stride type");
- if (stride_t->_hi < 0) { // Down-counter loop
- swap(lo, hi);
- return TypeInt::make(MIN2(lo->_lo, hi->_lo) , hi->_hi, 3);
- } else if (stride_t->_lo >= 0) {
- return TypeInt::make(lo->_lo, MAX2(lo->_hi, hi->_hi), 3);
+ BoolTest::mask bt = l->loopexit()->test_trip();
+ // If the loop exit condition is "not equal", the condition
+ // would not trigger if init > limit (if stride > 0) or if
+ // init < limit if (stride > 0) so we can't deduce bounds
+ // for the iv from the exit condition.
+ if (bt != BoolTest::ne) {
+ if (stride_t->_hi < 0) { // Down-counter loop
+ swap(lo, hi);
+ return TypeInt::make(MIN2(lo->_lo, hi->_lo) , hi->_hi, 3);
+ } else if (stride_t->_lo >= 0) {
+ return TypeInt::make(lo->_lo, MAX2(lo->_hi, hi->_hi), 3);
+ }
}
}
}
@@ -933,7 +940,7 @@
// before the special code for counted loop above has a chance
// to run (that is as long as the type of the backedge's control
// is top), we might end up with non monotonic types
- return phase->type(in(LoopNode::EntryControl));
+ return phase->type(in(LoopNode::EntryControl))->filter_speculative(_type);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/TestCountedLoopBadIVRange.java Mon Nov 13 14:53:28 2017 -0500
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. 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 8190375
+ * @summary Bad range for IV phi when exit condition is a not equal test
+ * @run main/othervm -XX:-TieredCompilation TestCountedLoopBadIVRange
+ *
+ */
+
+
+public class TestCountedLoopBadIVRange {
+
+ static int test1(int[] arr) {
+ int j = 0;
+ int res = 0;
+ for (int i = 0; i < 2; i++) {
+ // When entered with j == 10, exit condition never
+ // succeeds so range of values for j can't be computed
+ // from exit condition
+ for (; j != 5; j++) {
+ if (j >= 20) {
+ break;
+ }
+ res += arr[j];
+ }
+ j = 10;
+ }
+ return res;
+ }
+
+ static int test2(int[] arr) {
+ int j = 10;
+ int res = 0;
+ for (int i = 0; i < 2; i++) {
+ // Same as above but loop variable is decreasing
+ for (; j != 5; j--) {
+ if (j < 0) {
+ break;
+ }
+ res += arr[j];
+ }
+ j = 1;
+ }
+ return res;
+ }
+
+ public static void main(String[] args) {
+ int[] arr = new int[20];
+ for (int i = 0; i < arr.length; i++) {
+ arr[i] = i;
+ }
+ for (int i = 0; i < 20_000; i++) {
+ int res = test1(arr);
+ if (res != 155) {
+ throw new RuntimeException("Incorrect result " + res);
+ }
+ res = test2(arr);
+ if (res != 41) {
+ throw new RuntimeException("Incorrect result " + res);
+ }
+ }
+ }
+}