-
Bug
-
Resolution: Fixed
-
P2
-
9, 10, 11, 15, 16
-
b09
-
generic
-
generic
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8251066 | 15.0.2 | Fei Yang | P2 | Resolved | Fixed | b01 |
JDK-8251090 | 15.0.1 | Fei Yang | P2 | Resolved | Fixed | b04 |
JDK-8250862 | 15 | Fei Yang | P2 | Resolved | Fixed | b35 |
JDK-8252448 | 13.0.5 | Fei Yang | P2 | Resolved | Fixed | b01 |
JDK-8251346 | 11.0.10-oracle | Fei Yang | P2 | Closed | Fixed | b01 |
JDK-8251051 | 11.0.9 | Fei Yang | P2 | Resolved | Fixed | b02 |
Test case:
public class TestFoldCompares {
public int test() {
byte by = -37;
int result = 1;
int iArr[] = new int[6];
for (int i = 0; i < iArr.length; i++) {
iArr[i] = 0;
}
for (int i = 16; i < 308; i++) {
result *= i;
if ((result--) <= (++by)) {
continue;
}
for (int j = 3; j < 86; j++) {
for (int k = 1; k < 2; k++) {
result >>= 25;
}
for (int k = 1; k < 2; k += 3) {
try {
iArr[k] = (16986 / result);
} catch (ArithmeticException a_e) {
}
result = k;
}
}
}
return result;
}
public static void main(String[] args) {
TestFoldCompares obj = new TestFoldCompares();
for (int i = 0; i < 10; i++) {
int result = obj.test();
if (result != 1) {
throw new RuntimeException("Test failed.");
}
}
System.out.println("Test passed.");
}
}
$ java TestFoldCompares
--------------- T H R E A D ---------------
Current thread (0x0000ffff8049dc80): JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=123223, stack(0x0000ffff08131000,0x0000ffff08331000)]
Current CompileTask:
C2: 1214 53 % ! 4 TestFoldCompares::test @ 77 (140 bytes)
Stack: [0x0000ffff08131000,0x0000ffff08331000], sp=0x0000ffff0832bb90, free space=2026k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x41bb6c] Node::is_Phi() const+0xc
V [libjvm.so+0x1085be4] ok_to_convert(Node*, Node*)+0x18
V [libjvm.so+0x1086024] SubINode::Ideal(PhaseGVN*, bool)+0x3fc
V [libjvm.so+0xee1778] PhaseGVN::apply_ideal(Node*, bool)+0x70
V [libjvm.so+0xee2ff8] PhaseIterGVN::transform_old(Node*)+0xf8
V [libjvm.so+0xee2ef8] PhaseIterGVN::transform(Node*)+0x8c
V [libjvm.so+0x99b0cc] IfNode::fold_compares_helper(ProjNode*, ProjNode*, ProjNode*, PhaseIterGVN*)+0xc14
V [libjvm.so+0x99c3a0] IfNode::fold_compares(PhaseIterGVN*)+0x17c
V [libjvm.so+0x99cb74] IfNode::Ideal(PhaseGVN*, bool)+0xb4
V [libjvm.so+0xee1778] PhaseGVN::apply_ideal(Node*, bool)+0x70
V [libjvm.so+0xee2ff8] PhaseIterGVN::transform_old(Node*)+0xf8
V [libjvm.so+0xee2dac] PhaseIterGVN::optimize()+0x150
V [libjvm.so+0x6b7f1c] Compile::Optimize()+0x930
V [libjvm.so+0x6b1a64] Compile::Compile(ciEnv*, ciMethod*, int, bool, bool, bool, bool, DirectiveSet*)+0xc6c
V [libjvm.so+0x5a31c4] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x158
V [libjvm.so+0x6cc678] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x784
V [libjvm.so+0x6cb438] CompileBroker::compiler_thread_loop()+0x378
V [libjvm.so+0x1107334] compiler_thread_entry(JavaThread*, Thread*)+0x84
V [libjvm.so+0x1102554] JavaThread::thread_main_inner()+0x174
V [libjvm.so+0x11023cc] JavaThread::run()+0x1a0
V [libjvm.so+0x10fe2e4] Thread::call_run()+0x19c
V [libjvm.so+0xe7e668] thread_native_entry(Thread*)+0x1e4
C [libpthread.so.0+0x78bc] start_thread+0x19c
For the following logic in IfNode::fold_compares_helper:
995 if (lo && hi) {
996 // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo))
997 Node* adjusted_val = igvn->transform(new SubINode(n, lo));
998 if (adjusted_lim == NULL) {
999 adjusted_lim = igvn->transform(new SubINode(hi, lo));
1000 }
At line 997, we have:
(gdb) p lo->dump()
641 AddI === _ 513 92 [[]]
$1 = void
After the transformation at line 997, we have
(gdb) p lo->dump()
641 AddI === _ _ _ [[]] [34200641]
$3 = void
This node was used at line 999, which triggers the crash.
Proposed fix:
diff -r 14d51ff49d6e src/hotspot/share/opto/ifnode.cpp
--- a/src/hotspot/share/opto/ifnode.cpp Sat Jul 25 16:40:10 2020 +0800
+++ b/src/hotspot/share/opto/ifnode.cpp Mon Jul 27 10:13:12 2020 +0800
@@ -1408,7 +1408,10 @@
if (in(0) == NULL) return NULL; // Dead loop?
PhaseIterGVN* igvn = phase->is_IterGVN();
+ bool saved_delay_transform = igvn->delay_transform();
+ igvn->set_delay_transform(true);
Node* result = fold_compares(igvn);
+ igvn->set_delay_transform(saved_delay_transform);
if (result != NULL) {
return result;
}
public class TestFoldCompares {
public int test() {
byte by = -37;
int result = 1;
int iArr[] = new int[6];
for (int i = 0; i < iArr.length; i++) {
iArr[i] = 0;
}
for (int i = 16; i < 308; i++) {
result *= i;
if ((result--) <= (++by)) {
continue;
}
for (int j = 3; j < 86; j++) {
for (int k = 1; k < 2; k++) {
result >>= 25;
}
for (int k = 1; k < 2; k += 3) {
try {
iArr[k] = (16986 / result);
} catch (ArithmeticException a_e) {
}
result = k;
}
}
}
return result;
}
public static void main(String[] args) {
TestFoldCompares obj = new TestFoldCompares();
for (int i = 0; i < 10; i++) {
int result = obj.test();
if (result != 1) {
throw new RuntimeException("Test failed.");
}
}
System.out.println("Test passed.");
}
}
$ java TestFoldCompares
--------------- T H R E A D ---------------
Current thread (0x0000ffff8049dc80): JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=123223, stack(0x0000ffff08131000,0x0000ffff08331000)]
Current CompileTask:
C2: 1214 53 % ! 4 TestFoldCompares::test @ 77 (140 bytes)
Stack: [0x0000ffff08131000,0x0000ffff08331000], sp=0x0000ffff0832bb90, free space=2026k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x41bb6c] Node::is_Phi() const+0xc
V [libjvm.so+0x1085be4] ok_to_convert(Node*, Node*)+0x18
V [libjvm.so+0x1086024] SubINode::Ideal(PhaseGVN*, bool)+0x3fc
V [libjvm.so+0xee1778] PhaseGVN::apply_ideal(Node*, bool)+0x70
V [libjvm.so+0xee2ff8] PhaseIterGVN::transform_old(Node*)+0xf8
V [libjvm.so+0xee2ef8] PhaseIterGVN::transform(Node*)+0x8c
V [libjvm.so+0x99b0cc] IfNode::fold_compares_helper(ProjNode*, ProjNode*, ProjNode*, PhaseIterGVN*)+0xc14
V [libjvm.so+0x99c3a0] IfNode::fold_compares(PhaseIterGVN*)+0x17c
V [libjvm.so+0x99cb74] IfNode::Ideal(PhaseGVN*, bool)+0xb4
V [libjvm.so+0xee1778] PhaseGVN::apply_ideal(Node*, bool)+0x70
V [libjvm.so+0xee2ff8] PhaseIterGVN::transform_old(Node*)+0xf8
V [libjvm.so+0xee2dac] PhaseIterGVN::optimize()+0x150
V [libjvm.so+0x6b7f1c] Compile::Optimize()+0x930
V [libjvm.so+0x6b1a64] Compile::Compile(ciEnv*, ciMethod*, int, bool, bool, bool, bool, DirectiveSet*)+0xc6c
V [libjvm.so+0x5a31c4] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x158
V [libjvm.so+0x6cc678] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x784
V [libjvm.so+0x6cb438] CompileBroker::compiler_thread_loop()+0x378
V [libjvm.so+0x1107334] compiler_thread_entry(JavaThread*, Thread*)+0x84
V [libjvm.so+0x1102554] JavaThread::thread_main_inner()+0x174
V [libjvm.so+0x11023cc] JavaThread::run()+0x1a0
V [libjvm.so+0x10fe2e4] Thread::call_run()+0x19c
V [libjvm.so+0xe7e668] thread_native_entry(Thread*)+0x1e4
C [libpthread.so.0+0x78bc] start_thread+0x19c
For the following logic in IfNode::fold_compares_helper:
995 if (lo && hi) {
996 // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo))
997 Node* adjusted_val = igvn->transform(new SubINode(n, lo));
998 if (adjusted_lim == NULL) {
999 adjusted_lim = igvn->transform(new SubINode(hi, lo));
1000 }
At line 997, we have:
(gdb) p lo->dump()
641 AddI === _ 513 92 [[]]
$1 = void
After the transformation at line 997, we have
(gdb) p lo->dump()
641 AddI === _ _ _ [[]] [34200641]
$3 = void
This node was used at line 999, which triggers the crash.
Proposed fix:
diff -r 14d51ff49d6e src/hotspot/share/opto/ifnode.cpp
--- a/src/hotspot/share/opto/ifnode.cpp Sat Jul 25 16:40:10 2020 +0800
+++ b/src/hotspot/share/opto/ifnode.cpp Mon Jul 27 10:13:12 2020 +0800
@@ -1408,7 +1408,10 @@
if (in(0) == NULL) return NULL; // Dead loop?
PhaseIterGVN* igvn = phase->is_IterGVN();
+ bool saved_delay_transform = igvn->delay_transform();
+ igvn->set_delay_transform(true);
Node* result = fold_compares(igvn);
+ igvn->set_delay_transform(saved_delay_transform);
if (result != NULL) {
return result;
}
- backported by
-
JDK-8250862 C2 crash in IfNode::fold_compares
- Resolved
-
JDK-8251051 C2 crash in IfNode::fold_compares
- Resolved
-
JDK-8251066 C2 crash in IfNode::fold_compares
- Resolved
-
JDK-8251090 C2 crash in IfNode::fold_compares
- Resolved
-
JDK-8252448 C2 crash in IfNode::fold_compares
- Resolved
-
JDK-8251346 C2 crash in IfNode::fold_compares
- Closed
(1 backported by)