1 /*
2  * Copyright (c) 2018, 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 8214994
27  * @summary The split-if optimization fails because an unexpected Opaque1 is encountered.
28  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:-BackgroundCompilation
29  *                   compiler.loopopts.TestSplitIfOpaque1
30  */
31 
32 package compiler.loopopts;
33 
34 public class TestSplitIfOpaque1 {
35 
36     static class MyClass {
37         int f;
MyClass(int f)38         MyClass(int f) {
39             this.f = f;
40         }
41     }
42 
43     // The inner loop is found to be a counted loop and a loop limit check
44     // is added by updating the Opaque1 input of the predicate template.
45     // This Opaque1 node is then pushed upwards to before the predicates of
46     // the outer loop and ends up right after the second 'if (b)'.
47     // The split-if optimization kicks in and splits the first predicate of
48     // the outer loop (an "obj != NULL" check) through the 'if (b)' region.
49     // We fail because the region contains an unexpected Opaque1 node.
test1(boolean b, int limit, MyClass obj)50     static int test1(boolean b, int limit, MyClass obj) {
51         int res = 0;
52         MyClass notNull = new MyClass(42);
53         if (b) {
54             limit = 100;
55         }
56         if (b) {
57             obj = notNull;
58         }
59         for (int i = 0; i < 1000; ++i) {
60             res += obj.f;
61             for (int j = 0; j <= limit; ++j) {
62                 // Empty
63             }
64         }
65         return res;
66     }
67 
68     // Same as test1 but triggers slightly different failure mode
test2(boolean b, int limit, MyClass obj, int[] array)69     static int test2(boolean b, int limit, MyClass obj, int[] array) {
70         int res = 0;
71         MyClass notNull = new MyClass(12);
72         if (b) {
73             limit = 100;
74         }
75         if (b) {
76             obj = notNull;
77         }
78         for (int i = 0; i < 1000; ++i) {
79             res += obj.f;
80             for (int j = 0; j <= limit; ++j) {
81                 array[j] = j;
82             }
83         }
84         return res;
85     }
86 
main(String[] args)87     public static void main(String[] args) {
88         MyClass obj = new MyClass(42);
89         int[] array = new int[101];
90         for (int i = 0; i < 20_000; i++) {
91             test1(true, 50, obj);
92             test1(false, 100, obj);
93             test2(true, 50, obj, array);
94             test2(false, 100, obj, array);
95         }
96     }
97 }
98