1 /*
2  * Copyright (c) 2018, Red Hat, Inc. 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 8193130 8203915
27  * @summary Bad graph when unrolled loop bounds conflicts with range checks
28  * @requires vm.flavor == "server"
29  *
30  * @run main/othervm IterationSplitPredicateInconsistency
31  * @run main/othervm -XX:-UseLoopPredicate IterationSplitPredicateInconsistency
32  * @run main/othervm -XX:LoopStripMiningIter=0 IterationSplitPredicateInconsistency
33  *
34  */
35 
36 public class IterationSplitPredicateInconsistency {
37     static volatile int barrier;
38 
39     // Pollute profile so loop appears to run for a large number of iterations
test1_helper(int start, int stop, double[] array1, double[] array2, int exit)40     static boolean test1_helper(int start, int stop, double[] array1, double[] array2, int exit) {
41         for (int i = start; i < stop; i++) {
42             array1[i] = array2[i];
43             if (i == exit) {
44                 return true;
45             }
46             barrier = 0x42;
47         }
48         return false;
49     }
50 
test1(int start, double[] array2, int exit)51     static double[] test1(int start, double[] array2, int exit) {
52         double[] array1 = new double[10];
53         // Predication moves range checks out of loop and
54         // pre/main/post loops are created. The main loop is unrolled
55         // several times to the point where it's never executed but
56         // compiler can't tell from the loop bounds alone. The lower
57         // bound of the loop is negative and would cause range checks
58         // (that were removed from the loop body) to fail.
59         if (test1_helper(start, 5, array1, array2, exit)) {
60             return null;
61         }
62         return array1;
63     }
64 
65     // Same as above with other combinations of increasing/decreasing
66     // loops, positive/negative stride
test2_helper(int start, int stop, double[] array1, double[] array2, int exit)67     static boolean test2_helper(int start, int stop, double[] array1, double[] array2, int exit) {
68         for (int i = start-1; i >= stop; i--) {
69             array1[i] = array2[i];
70             if (i == exit) {
71                 return true;
72             }
73             barrier = 0x42;
74         }
75         return false;
76     }
77 
test2(int start, double[] array2, int exit)78     static double[] test2(int start, double[] array2, int exit) {
79         double[] array1 = new double[10];
80         if (test2_helper(start, 0, array1, array2, exit)) {
81             return null;
82         }
83         return array1;
84     }
85 
test3_helper(int start, int stop, double[] array1, double[] array2, int exit)86     static boolean test3_helper(int start, int stop, double[] array1, double[] array2, int exit) {
87         for (int i = start; i < stop; i++) {
88             array1[stop-i-1] = array2[stop-i-1];
89             if (i == exit) {
90                 return true;
91             }
92             barrier = 0x42;
93         }
94         return false;
95     }
96 
test3(int start, double[] array2, int exit)97     static double[] test3(int start, double[] array2, int exit) {
98         double[] array1 = new double[5];
99         if (test3_helper(start, 5, array1, array2, exit)) {
100             return null;
101         }
102         return array1;
103     }
104 
test4_helper(int start, int stop, int from, double[] array1, double[] array2, int exit)105     static boolean test4_helper(int start, int stop, int from, double[] array1, double[] array2, int exit) {
106         for (int i = start-1; i >= stop; i--) {
107             array1[from-i-1] = array2[from-i-1];
108             if (i == exit) {
109                 return true;
110             }
111             barrier = 0x42;
112         }
113         return false;
114     }
115 
test4(int start, double[] array2, int exit)116     static double[] test4(int start, double[] array2, int exit) {
117         double[] array1 = new double[5];
118         if (test4_helper(start, 0, 5, array1, array2, exit)) {
119             return null;
120         }
121         return array1;
122     }
123 
main(String[] args)124     public static void main(String[] args) {
125         double[] array2 = new double[10];
126         double[] array3 = new double[1000];
127         for (int i = 0; i < 20_000; i++) {
128             test1_helper(0, 1000, array3, array3, 998);
129             test1(0, array2, 999);
130             test1(0, array2, 4);
131             test2_helper(1000, 0, array3, array3, 1);
132             test2(5, array2, 999);
133             test2(5, array2, 1);
134             test3_helper(0, 1000, array3, array3, 998);
135             test3(0, array2, 999);
136             test3(0, array2, 4);
137             test4_helper(1000, 0, 1000, array3, array3, 1);
138             test4(5, array2, 999);
139             test4(5, array2, 1);
140         }
141     }
142 }
143