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