1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 8139771
27 * @summary Eliminating CastPP nodes at Phis when they all come from a unique input may cause crash
28 * @requires vm.gc=="Serial" | vm.gc=="Parallel"
29 *
30 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
31 *      -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+StressGCM
32 *      compiler.controldependency.TestEliminatedCastPPAtPhi
33 *
34 */
35
36package compiler.controldependency;
37
38public class TestEliminatedCastPPAtPhi {
39
40    static TestEliminatedCastPPAtPhi saved;
41    static TestEliminatedCastPPAtPhi saved_not_null;
42
43    int f;
44
45    static int test(TestEliminatedCastPPAtPhi obj, int[] array, boolean flag) {
46        int ret = array[0] + array[20];
47        saved = obj;
48        if (obj == null) {
49            return ret;
50        }
51        saved_not_null = obj;
52
53        // empty loop to be optimized out. Delays range check smearing
54        // for the array access below until the if diamond is
55        // optimized out
56        int i = 0;
57        for (; i < 10; i++);
58
59        ret += array[i];
60
61        TestEliminatedCastPPAtPhi res;
62        if (flag) {
63            // load is optimized out and res is obj here
64            res = saved;
65        } else {
66            // load is optimized out and res is non null CastPP of res here
67            res = saved_not_null;
68        }
69        // null check + CastPP here for res field load below
70
71        // 1) null check is pushed in the branches of the if above by
72        // split through phi because res is non null in the second
73        // branch and the null check can be optimized out in that
74        // branch. The Castpp stays here.
75
76        // 2) null check in the first branch is also optimized out
77        // because a dominating null check is found (the explicit null
78        // check at the beggining of the test)
79
80        // 3) the Phi for the if above merges a CastPP'ed value and
81        // the same value so it's optimized out and replaced by the
82        // uncasted value: obj
83
84        // 4) the if above has 2 empty branches so it's optimized
85        // out. The control of the CastPP that is still here is now
86        // the success branch of the range check for the array access
87        // above
88
89        // 5) the loop above is optimized out, i = 10, the range check
90        // for the array access above is optimized out and all its
91        // uses are replaced by the range check for the array accesses
92        // at the beginning of the method. The castPP here is one of
93        // the uses and so its control is now the range check at the
94        // beginning of the method: the control of the CastPP bypasses
95        // the explicit null check
96
97        return ret + res.f;
98    }
99
100    static public void main(String[] args) {
101        int[] array = new int[100];
102        TestEliminatedCastPPAtPhi obj = new TestEliminatedCastPPAtPhi();
103        for (int i = 0; i < 20000; i++) {
104            test(obj, array, (i%2) == 0);
105        }
106        test(null, array, true);
107    }
108
109}
110