public class T3 {
    public static void main (String[] args) {
        float res = test(false, false);
        System.out.println("res: " + res);
    }
    public static float test(boolean flag1, boolean flag2) {
        float ret = 1.0f;
        int x = 0;
        LOOP1:
        for (int i = 1; i < 1000000; i *= 2) { // about 20 iterations
            if (i % 5 != 0) { // SKIP1
                LOOP2:
                for (int j = 1; j < 1000000; j *= 2) { // about 20 iterations
                    if (j % 5 != 0) { // SKIP2
                        if (x == 0) { // eventually always false -> continue statements float out of loop
                            ret *= 1.0001;
                            if (j > 100) {
                                // exhaust -XX:PerMethodTrapLimit=10
                                // Each of the LOOP3 for-loops should do more than 100k iterations
                                // which triggers OSR compilation. We hit the first loop, trigger OSR.
                                // At the exit of that loop, we set an "unstable_if" uncommon_trap.
                                // In the OSR execution, we eventually leave the loop and trigger that trap.
                                // We continue in interpreter to next loop, and trigger OSR compilation again.
                                // This game continues, until we have the PerMethodTrapLimit exhausted,
                                // then we do no longer place any traps for "unstable_if", and compile the rest
                                // of the method.
                                // We must exhaust the trap limit before we set "x = 1", else we never come
                                // back here, and cannot generate an irreducible loop.
                                // If you want a simpler graph: remove some of these loops, and set trap limit lower.
                                float limit = 3.0E7f;
                                float factor = 1.000001f;
                                LOOP3:
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                for (float m = 1.0f; m < limit; m *= factor) { ret *= 0.99999f; }
                                x = 1;
                            }
                            int y = 77;
                            for (int e = 0; e < 77; e++) {
                                y -= x; // empty_loop, once we know that x == 1
                            }
                            if (y == 0) {
                                // always true after OSR -> cut off ENTRY1 and ENTRY2
                                return ret;
                            }
                            ret += 0.01;
                            if (ret > 20000) {
                                ret = 7.0f;
                                continue LOOP1; // ENTRY1
                            }
                            // back to LOOP2 -> ENTRY2
                        } // end if (x == 0)
                    } // end SKIP2
                } // end LOOP2
            } // end SKIP1
        } // end LOOP1
        return ret;
    }
}
