class Reduced2 {
    static final int N = 400;
    static boolean flag = false;

    static void allocateArrays() {
        for (int i = 0; 200_000 > i; ++i) {
            int[] a = new int[N];
        }
        // Makes GC more likely.
        // Without it I could not reproduce it on slowdebug,
        // but only with fastdebug.
        if (flag) { System.gc(); }
        flag = !flag;
    }

    static int[] test() {
        int a[] = new int[N];
        // We must make sure that no CastP2X happens before
        // the call below, otherwise we may have an old oop.
        allocateArrays();
        // The CastP2X for the aliasing runtime check should
        // only be emitted after the call, to ensure we only
        // deal with oops that are updated if there is a GC
        // that could move our allocated array.

        // Not fully sure why we need the outer loop, but maybe
        // it is needed so that a part of the check is hoisted,
        // and the floats up, over the call if we do not set
        // the ctrl.
        for (int k = 0; k < 500; k++) {
            for (int i = 1; i < 69; i++) {
                // Aliasing references -> needs runtime check,
                // should always fail.
                a[i] =  14;
                a[4] -= 14;
                // The range computation for the constant access
                // produces a shape:
                //   AddL(CastP2X(a), 0x20)
                // And this shape only depends on a, so it could
                // easily float above the call to allocateArrays
                // if we do not set a ctrl that prevents that.
            }
        }
        return a;
    }

    public static void main(String[] args) {
        int[] gold = test();
        for (int r = 0; r < 10; r++) {
            int[] a = test();
            System.out.println("a[4]: " + a[4]);
            if (a[4] != gold[4]) {
                throw new RuntimeException("wrong value " + gold[4] + " " + a[4]);
            }
        }
    }
}
