Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8250609

C2 crash in IfNode::fold_compares

    XMLWordPrintable

Details

    • b09
    • generic
    • generic
    • Verified

    Backports

      Description

        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;
           }

        Attachments

          Issue Links

            Activity

              People

                fyang Fei Yang
                fyang Fei Yang
                Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: