1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker // 18*795d594fSAndroid Build Coastguard Worker // Test on loop optimizations, in particular around common induction. 19*795d594fSAndroid Build Coastguard Worker // 20*795d594fSAndroid Build Coastguard Worker public class Main { 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker static int sResult; 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker // 25*795d594fSAndroid Build Coastguard Worker // Various sequence variables used in bound checks. 26*795d594fSAndroid Build Coastguard Worker // 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linear(int[]) BCE (before) 29*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 30*795d594fSAndroid Build Coastguard Worker // 31*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linear(int[]) BCE (after) 32*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 33*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linear(int[] x)34*795d594fSAndroid Build Coastguard Worker private static int linear(int[] x) { 35*795d594fSAndroid Build Coastguard Worker int result = 0; 36*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 37*795d594fSAndroid Build Coastguard Worker result += x[i]; 38*795d594fSAndroid Build Coastguard Worker } 39*795d594fSAndroid Build Coastguard Worker return result; 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDown(int[]) BCE (before) 43*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 44*795d594fSAndroid Build Coastguard Worker // 45*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDown(int[]) BCE (after) 46*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 47*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearDown(int[] x)48*795d594fSAndroid Build Coastguard Worker private static int linearDown(int[] x) { 49*795d594fSAndroid Build Coastguard Worker int result = 0; 50*795d594fSAndroid Build Coastguard Worker for (int i = x.length - 1; i >= 0; i--) { 51*795d594fSAndroid Build Coastguard Worker result += x[i]; 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker return result; 54*795d594fSAndroid Build Coastguard Worker } 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearObscure(int[]) BCE (before) 57*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 58*795d594fSAndroid Build Coastguard Worker // 59*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearObscure(int[]) BCE (after) 60*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 61*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearObscure(int[] x)62*795d594fSAndroid Build Coastguard Worker private static int linearObscure(int[] x) { 63*795d594fSAndroid Build Coastguard Worker int result = 0; 64*795d594fSAndroid Build Coastguard Worker for (int i = x.length - 1; i >= 0; i--) { 65*795d594fSAndroid Build Coastguard Worker int k = i + 5; 66*795d594fSAndroid Build Coastguard Worker result += x[k - 5]; 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker return result; 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before) 72*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 73*795d594fSAndroid Build Coastguard Worker // 74*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after) 75*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 76*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearVeryObscure(int[] x)77*795d594fSAndroid Build Coastguard Worker private static int linearVeryObscure(int[] x) { 78*795d594fSAndroid Build Coastguard Worker int result = 0; 79*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 80*795d594fSAndroid Build Coastguard Worker int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i; 81*795d594fSAndroid Build Coastguard Worker result += x[k - 5]; 82*795d594fSAndroid Build Coastguard Worker } 83*795d594fSAndroid Build Coastguard Worker return result; 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.hiddenStride(int[]) BCE (before) 87*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 88*795d594fSAndroid Build Coastguard Worker // 89*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.hiddenStride(int[]) BCE (after) 90*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 91*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize hiddenStride(int[] a)92*795d594fSAndroid Build Coastguard Worker static int hiddenStride(int[] a) { 93*795d594fSAndroid Build Coastguard Worker int result = 0; 94*795d594fSAndroid Build Coastguard Worker for (int i = 1; i <= 1; i++) { 95*795d594fSAndroid Build Coastguard Worker // Obscured unit stride. 96*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < a.length; j += i) { 97*795d594fSAndroid Build Coastguard Worker result += a[j]; 98*795d594fSAndroid Build Coastguard Worker } 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker return result; 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWhile(int[]) BCE (before) 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 105*795d594fSAndroid Build Coastguard Worker // 106*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWhile(int[]) BCE (after) 107*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 108*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWhile(int[] x)109*795d594fSAndroid Build Coastguard Worker private static int linearWhile(int[] x) { 110*795d594fSAndroid Build Coastguard Worker int i = 0; 111*795d594fSAndroid Build Coastguard Worker int result = 0; 112*795d594fSAndroid Build Coastguard Worker while (i < x.length) { 113*795d594fSAndroid Build Coastguard Worker result += x[i++]; 114*795d594fSAndroid Build Coastguard Worker } 115*795d594fSAndroid Build Coastguard Worker return result; 116*795d594fSAndroid Build Coastguard Worker } 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before) 119*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 120*795d594fSAndroid Build Coastguard Worker // 121*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after) 122*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 123*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearThreeWayPhi(int[] x)124*795d594fSAndroid Build Coastguard Worker private static int linearThreeWayPhi(int[] x) { 125*795d594fSAndroid Build Coastguard Worker int result = 0; 126*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; ) { 127*795d594fSAndroid Build Coastguard Worker if (x[i] == 5) { 128*795d594fSAndroid Build Coastguard Worker i++; 129*795d594fSAndroid Build Coastguard Worker continue; 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker result += x[i++]; 132*795d594fSAndroid Build Coastguard Worker } 133*795d594fSAndroid Build Coastguard Worker return result; 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before) 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 138*795d594fSAndroid Build Coastguard Worker // 139*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after) 140*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 141*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearFourWayPhi(int[] x)142*795d594fSAndroid Build Coastguard Worker private static int linearFourWayPhi(int[] x) { 143*795d594fSAndroid Build Coastguard Worker int result = 0; 144*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; ) { 145*795d594fSAndroid Build Coastguard Worker if (x[i] == 5) { 146*795d594fSAndroid Build Coastguard Worker i++; 147*795d594fSAndroid Build Coastguard Worker continue; 148*795d594fSAndroid Build Coastguard Worker } else if (x[i] == 6) { 149*795d594fSAndroid Build Coastguard Worker i++; 150*795d594fSAndroid Build Coastguard Worker result += 7; 151*795d594fSAndroid Build Coastguard Worker continue; 152*795d594fSAndroid Build Coastguard Worker } 153*795d594fSAndroid Build Coastguard Worker result += x[i++]; 154*795d594fSAndroid Build Coastguard Worker } 155*795d594fSAndroid Build Coastguard Worker return result; 156*795d594fSAndroid Build Coastguard Worker } 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before) 159*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 160*795d594fSAndroid Build Coastguard Worker // 161*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after) 162*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 163*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize wrapAroundThenLinear(int[] x)164*795d594fSAndroid Build Coastguard Worker private static int wrapAroundThenLinear(int[] x) { 165*795d594fSAndroid Build Coastguard Worker // Loop with wrap around (length - 1, 0, 1, 2, ..). 166*795d594fSAndroid Build Coastguard Worker int w = x.length - 1; 167*795d594fSAndroid Build Coastguard Worker int result = 0; 168*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 169*795d594fSAndroid Build Coastguard Worker result += x[w]; 170*795d594fSAndroid Build Coastguard Worker w = i; 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker return result; 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before) 176*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 177*795d594fSAndroid Build Coastguard Worker // 178*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after) 179*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 180*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize wrapAroundThenLinearThreeWayPhi(int[] x)181*795d594fSAndroid Build Coastguard Worker private static int wrapAroundThenLinearThreeWayPhi(int[] x) { 182*795d594fSAndroid Build Coastguard Worker // Loop with wrap around (length - 1, 0, 1, 2, ..). 183*795d594fSAndroid Build Coastguard Worker int w = x.length - 1; 184*795d594fSAndroid Build Coastguard Worker int result = 0; 185*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; ) { 186*795d594fSAndroid Build Coastguard Worker if (x[w] == 1) { 187*795d594fSAndroid Build Coastguard Worker w = i++; 188*795d594fSAndroid Build Coastguard Worker continue; 189*795d594fSAndroid Build Coastguard Worker } 190*795d594fSAndroid Build Coastguard Worker result += x[w]; 191*795d594fSAndroid Build Coastguard Worker w = i++; 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker return result; 194*795d594fSAndroid Build Coastguard Worker } 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before) 197*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 198*795d594fSAndroid Build Coastguard Worker // 199*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after) 200*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 201*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithParameter(int n)202*795d594fSAndroid Build Coastguard Worker private static int[] linearWithParameter(int n) { 203*795d594fSAndroid Build Coastguard Worker int[] x = new int[n]; 204*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 205*795d594fSAndroid Build Coastguard Worker x[i] = i; 206*795d594fSAndroid Build Coastguard Worker } 207*795d594fSAndroid Build Coastguard Worker return x; 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker 210*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before) 211*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 212*795d594fSAndroid Build Coastguard Worker // 213*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after) 214*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 215*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearCopy(int x[])216*795d594fSAndroid Build Coastguard Worker private static int[] linearCopy(int x[]) { 217*795d594fSAndroid Build Coastguard Worker int n = x.length; 218*795d594fSAndroid Build Coastguard Worker int y[] = new int[n]; 219*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 220*795d594fSAndroid Build Coastguard Worker y[i] = x[i]; 221*795d594fSAndroid Build Coastguard Worker } 222*795d594fSAndroid Build Coastguard Worker return y; 223*795d594fSAndroid Build Coastguard Worker } 224*795d594fSAndroid Build Coastguard Worker 225*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwo(int[]) BCE (before) 226*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 227*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 228*795d594fSAndroid Build Coastguard Worker // 229*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwo(int[]) BCE (after) 230*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 231*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearByTwo(int x[])232*795d594fSAndroid Build Coastguard Worker private static int linearByTwo(int x[]) { 233*795d594fSAndroid Build Coastguard Worker int n = x.length / 2; 234*795d594fSAndroid Build Coastguard Worker int result = 0; 235*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 236*795d594fSAndroid Build Coastguard Worker int ii = i << 1; 237*795d594fSAndroid Build Coastguard Worker result += x[ii]; 238*795d594fSAndroid Build Coastguard Worker result += x[ii + 1]; 239*795d594fSAndroid Build Coastguard Worker } 240*795d594fSAndroid Build Coastguard Worker return result; 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (before) 244*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 245*795d594fSAndroid Build Coastguard Worker // 246*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (after) 247*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 248*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearByTwoSkip1(int x[])249*795d594fSAndroid Build Coastguard Worker private static int linearByTwoSkip1(int x[]) { 250*795d594fSAndroid Build Coastguard Worker int result = 0; 251*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length / 2; i++) { 252*795d594fSAndroid Build Coastguard Worker result += x[2 * i]; 253*795d594fSAndroid Build Coastguard Worker } 254*795d594fSAndroid Build Coastguard Worker return result; 255*795d594fSAndroid Build Coastguard Worker } 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (before) 258*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 259*795d594fSAndroid Build Coastguard Worker // 260*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after) 261*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 262*795d594fSAndroid Build Coastguard Worker // 263*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after) 264*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearByTwoSkip2(int x[])265*795d594fSAndroid Build Coastguard Worker private static int linearByTwoSkip2(int x[]) { 266*795d594fSAndroid Build Coastguard Worker int result = 0; 267*795d594fSAndroid Build Coastguard Worker // This case is not optimized. 268*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i+=2) { 269*795d594fSAndroid Build Coastguard Worker result += x[i]; 270*795d594fSAndroid Build Coastguard Worker } 271*795d594fSAndroid Build Coastguard Worker return result; 272*795d594fSAndroid Build Coastguard Worker } 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithCompoundStride() BCE (before) 275*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 276*795d594fSAndroid Build Coastguard Worker // 277*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithCompoundStride() BCE (after) 278*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 279*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithCompoundStride()280*795d594fSAndroid Build Coastguard Worker private static int linearWithCompoundStride() { 281*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; 282*795d594fSAndroid Build Coastguard Worker int result = 0; 283*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= 12; ) { 284*795d594fSAndroid Build Coastguard Worker i++; 285*795d594fSAndroid Build Coastguard Worker result += x[i]; 286*795d594fSAndroid Build Coastguard Worker i++; 287*795d594fSAndroid Build Coastguard Worker } 288*795d594fSAndroid Build Coastguard Worker return result; 289*795d594fSAndroid Build Coastguard Worker } 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before) 292*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 293*795d594fSAndroid Build Coastguard Worker // 294*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after) 295*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 296*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithLargePositiveStride()297*795d594fSAndroid Build Coastguard Worker private static int linearWithLargePositiveStride() { 298*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 299*795d594fSAndroid Build Coastguard Worker int result = 0; 300*795d594fSAndroid Build Coastguard Worker int k = 0; 301*795d594fSAndroid Build Coastguard Worker // Range analysis has no problem with a trip-count defined by a 302*795d594fSAndroid Build Coastguard Worker // reasonably large positive stride far away from upper bound. 303*795d594fSAndroid Build Coastguard Worker for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) { 304*795d594fSAndroid Build Coastguard Worker result += x[k++]; 305*795d594fSAndroid Build Coastguard Worker } 306*795d594fSAndroid Build Coastguard Worker return result; 307*795d594fSAndroid Build Coastguard Worker } 308*795d594fSAndroid Build Coastguard Worker 309*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before) 310*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 311*795d594fSAndroid Build Coastguard Worker // 312*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after) 313*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 314*795d594fSAndroid Build Coastguard Worker // 315*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after) 316*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithVeryLargePositiveStride()317*795d594fSAndroid Build Coastguard Worker private static int linearWithVeryLargePositiveStride() { 318*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 319*795d594fSAndroid Build Coastguard Worker int result = 0; 320*795d594fSAndroid Build Coastguard Worker int k = 0; 321*795d594fSAndroid Build Coastguard Worker // Range analysis conservatively bails due to potential of wrap-around 322*795d594fSAndroid Build Coastguard Worker // arithmetic while computing the trip-count for this very large stride. 323*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) { 324*795d594fSAndroid Build Coastguard Worker result += x[k++]; 325*795d594fSAndroid Build Coastguard Worker } 326*795d594fSAndroid Build Coastguard Worker return result; 327*795d594fSAndroid Build Coastguard Worker } 328*795d594fSAndroid Build Coastguard Worker 329*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before) 330*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 331*795d594fSAndroid Build Coastguard Worker // 332*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after) 333*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 334*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithLargeNegativeStride()335*795d594fSAndroid Build Coastguard Worker private static int linearWithLargeNegativeStride() { 336*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 337*795d594fSAndroid Build Coastguard Worker int result = 0; 338*795d594fSAndroid Build Coastguard Worker int k = 0; 339*795d594fSAndroid Build Coastguard Worker // Range analysis has no problem with a trip-count defined by a 340*795d594fSAndroid Build Coastguard Worker // reasonably large negative stride far away from lower bound. 341*795d594fSAndroid Build Coastguard Worker for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) { 342*795d594fSAndroid Build Coastguard Worker result += x[k++]; 343*795d594fSAndroid Build Coastguard Worker } 344*795d594fSAndroid Build Coastguard Worker return result; 345*795d594fSAndroid Build Coastguard Worker } 346*795d594fSAndroid Build Coastguard Worker 347*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before) 348*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 349*795d594fSAndroid Build Coastguard Worker // 350*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after) 351*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 352*795d594fSAndroid Build Coastguard Worker // 353*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after) 354*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearWithVeryLargeNegativeStride()355*795d594fSAndroid Build Coastguard Worker private static int linearWithVeryLargeNegativeStride() { 356*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 357*795d594fSAndroid Build Coastguard Worker int result = 0; 358*795d594fSAndroid Build Coastguard Worker int k = 0; 359*795d594fSAndroid Build Coastguard Worker // Range analysis conservatively bails due to potential of wrap-around 360*795d594fSAndroid Build Coastguard Worker // arithmetic while computing the trip-count for this very large stride. 361*795d594fSAndroid Build Coastguard Worker for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) { 362*795d594fSAndroid Build Coastguard Worker result += x[k++]; 363*795d594fSAndroid Build Coastguard Worker } 364*795d594fSAndroid Build Coastguard Worker return result; 365*795d594fSAndroid Build Coastguard Worker } 366*795d594fSAndroid Build Coastguard Worker 367*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEUp() BCE (before) 368*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 369*795d594fSAndroid Build Coastguard Worker // 370*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEUp() BCE (after) 371*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 372*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearForNEUp()373*795d594fSAndroid Build Coastguard Worker private static int linearForNEUp() { 374*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 375*795d594fSAndroid Build Coastguard Worker int result = 0; 376*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != 10; i++) { 377*795d594fSAndroid Build Coastguard Worker result += x[i]; 378*795d594fSAndroid Build Coastguard Worker } 379*795d594fSAndroid Build Coastguard Worker return result; 380*795d594fSAndroid Build Coastguard Worker } 381*795d594fSAndroid Build Coastguard Worker 382*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEDown() BCE (before) 383*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 384*795d594fSAndroid Build Coastguard Worker // 385*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEDown() BCE (after) 386*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 387*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearForNEDown()388*795d594fSAndroid Build Coastguard Worker private static int linearForNEDown() { 389*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 390*795d594fSAndroid Build Coastguard Worker int result = 0; 391*795d594fSAndroid Build Coastguard Worker for (int i = 9; i != -1; i--) { 392*795d594fSAndroid Build Coastguard Worker result += x[i]; 393*795d594fSAndroid Build Coastguard Worker } 394*795d594fSAndroid Build Coastguard Worker return result; 395*795d594fSAndroid Build Coastguard Worker } 396*795d594fSAndroid Build Coastguard Worker 397*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (before) 398*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 399*795d594fSAndroid Build Coastguard Worker // 400*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (after) 401*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 402*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearForNEArrayLengthUp(int[] x)403*795d594fSAndroid Build Coastguard Worker private static int linearForNEArrayLengthUp(int[] x) { 404*795d594fSAndroid Build Coastguard Worker int result = 0; 405*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != x.length; i++) { 406*795d594fSAndroid Build Coastguard Worker result += x[i]; 407*795d594fSAndroid Build Coastguard Worker } 408*795d594fSAndroid Build Coastguard Worker return result; 409*795d594fSAndroid Build Coastguard Worker } 410*795d594fSAndroid Build Coastguard Worker 411*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (before) 412*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 413*795d594fSAndroid Build Coastguard Worker // 414*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (after) 415*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 416*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearForNEArrayLengthDown(int[] x)417*795d594fSAndroid Build Coastguard Worker private static int linearForNEArrayLengthDown(int[] x) { 418*795d594fSAndroid Build Coastguard Worker int result = 0; 419*795d594fSAndroid Build Coastguard Worker for (int i = x.length - 1; i != -1; i--) { 420*795d594fSAndroid Build Coastguard Worker result += x[i]; 421*795d594fSAndroid Build Coastguard Worker } 422*795d594fSAndroid Build Coastguard Worker return result; 423*795d594fSAndroid Build Coastguard Worker } 424*795d594fSAndroid Build Coastguard Worker 425*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDoWhileUp() BCE (before) 426*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 427*795d594fSAndroid Build Coastguard Worker // 428*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDoWhileUp() BCE (after) 429*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 430*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearDoWhileUp()431*795d594fSAndroid Build Coastguard Worker private static int linearDoWhileUp() { 432*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 433*795d594fSAndroid Build Coastguard Worker int result = 0; 434*795d594fSAndroid Build Coastguard Worker int i = 0; 435*795d594fSAndroid Build Coastguard Worker do { 436*795d594fSAndroid Build Coastguard Worker result += x[i++]; 437*795d594fSAndroid Build Coastguard Worker } while (i < 10); 438*795d594fSAndroid Build Coastguard Worker return result; 439*795d594fSAndroid Build Coastguard Worker } 440*795d594fSAndroid Build Coastguard Worker 441*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDoWhileDown() BCE (before) 442*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 443*795d594fSAndroid Build Coastguard Worker // 444*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDoWhileDown() BCE (after) 445*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 446*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearDoWhileDown()447*795d594fSAndroid Build Coastguard Worker private static int linearDoWhileDown() { 448*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 449*795d594fSAndroid Build Coastguard Worker int result = 0; 450*795d594fSAndroid Build Coastguard Worker int i = 9; 451*795d594fSAndroid Build Coastguard Worker do { 452*795d594fSAndroid Build Coastguard Worker result += x[i--]; 453*795d594fSAndroid Build Coastguard Worker } while (0 <= i); 454*795d594fSAndroid Build Coastguard Worker return result; 455*795d594fSAndroid Build Coastguard Worker } 456*795d594fSAndroid Build Coastguard Worker 457*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearLong() BCE (before) 458*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 459*795d594fSAndroid Build Coastguard Worker // 460*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearLong() BCE (after) 461*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 462*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearLong()463*795d594fSAndroid Build Coastguard Worker private static int linearLong() { 464*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 465*795d594fSAndroid Build Coastguard Worker int result = 0; 466*795d594fSAndroid Build Coastguard Worker // Induction on constant interval is done in higher precision than necessary, 467*795d594fSAndroid Build Coastguard Worker // but truncated at the use as subscript. 468*795d594fSAndroid Build Coastguard Worker for (long i = 0; i < 10; i++) { 469*795d594fSAndroid Build Coastguard Worker result += x[(int)i]; 470*795d594fSAndroid Build Coastguard Worker } 471*795d594fSAndroid Build Coastguard Worker return result; 472*795d594fSAndroid Build Coastguard Worker } 473*795d594fSAndroid Build Coastguard Worker 474*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearLongAlt(int[]) BCE (before) 475*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 476*795d594fSAndroid Build Coastguard Worker // 477*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearLongAlt(int[]) BCE (after) 478*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 479*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearLongAlt(int[] x)480*795d594fSAndroid Build Coastguard Worker private static int linearLongAlt(int[] x) { 481*795d594fSAndroid Build Coastguard Worker int result = 0; 482*795d594fSAndroid Build Coastguard Worker // Induction on array length is done in higher precision than necessary, 483*795d594fSAndroid Build Coastguard Worker // but truncated at the use as subscript. 484*795d594fSAndroid Build Coastguard Worker for (long i = 0; i < x.length; i++) { 485*795d594fSAndroid Build Coastguard Worker result += x[(int)i]; 486*795d594fSAndroid Build Coastguard Worker } 487*795d594fSAndroid Build Coastguard Worker return result; 488*795d594fSAndroid Build Coastguard Worker } 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearShort() BCE (before) 491*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 492*795d594fSAndroid Build Coastguard Worker // 493*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearShort() BCE (after) 494*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 495*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearShort()496*795d594fSAndroid Build Coastguard Worker private static int linearShort() { 497*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 498*795d594fSAndroid Build Coastguard Worker int result = 0; 499*795d594fSAndroid Build Coastguard Worker // Induction is done in short precision, but fits. 500*795d594fSAndroid Build Coastguard Worker for (short i = 0; i < 10; i++) { 501*795d594fSAndroid Build Coastguard Worker result += x[i]; 502*795d594fSAndroid Build Coastguard Worker } 503*795d594fSAndroid Build Coastguard Worker return result; 504*795d594fSAndroid Build Coastguard Worker } 505*795d594fSAndroid Build Coastguard Worker 506*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearChar() BCE (before) 507*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 508*795d594fSAndroid Build Coastguard Worker // 509*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearChar() BCE (after) 510*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 511*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearChar()512*795d594fSAndroid Build Coastguard Worker private static int linearChar() { 513*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 514*795d594fSAndroid Build Coastguard Worker int result = 0; 515*795d594fSAndroid Build Coastguard Worker // Induction is done in char precision, but fits. 516*795d594fSAndroid Build Coastguard Worker for (char i = 0; i < 10; i++) { 517*795d594fSAndroid Build Coastguard Worker result += x[i]; 518*795d594fSAndroid Build Coastguard Worker } 519*795d594fSAndroid Build Coastguard Worker return result; 520*795d594fSAndroid Build Coastguard Worker } 521*795d594fSAndroid Build Coastguard Worker 522*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByte() BCE (before) 523*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 524*795d594fSAndroid Build Coastguard Worker // 525*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearByte() BCE (after) 526*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 527*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearByte()528*795d594fSAndroid Build Coastguard Worker private static int linearByte() { 529*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 530*795d594fSAndroid Build Coastguard Worker int result = 0; 531*795d594fSAndroid Build Coastguard Worker // Induction is done in byte precision, but fits. 532*795d594fSAndroid Build Coastguard Worker for (byte i = 0; i < 10; i++) { 533*795d594fSAndroid Build Coastguard Worker result += x[i]; 534*795d594fSAndroid Build Coastguard Worker } 535*795d594fSAndroid Build Coastguard Worker return result; 536*795d594fSAndroid Build Coastguard Worker } 537*795d594fSAndroid Build Coastguard Worker 538*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before) 539*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 540*795d594fSAndroid Build Coastguard Worker // 541*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after) 542*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 543*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize invariantFromPreLoop(int[] x, int y)544*795d594fSAndroid Build Coastguard Worker private static int invariantFromPreLoop(int[] x, int y) { 545*795d594fSAndroid Build Coastguard Worker int result = 0; 546*795d594fSAndroid Build Coastguard Worker // Strange pre-loop that sets upper bound. 547*795d594fSAndroid Build Coastguard Worker int hi; 548*795d594fSAndroid Build Coastguard Worker while (true) { 549*795d594fSAndroid Build Coastguard Worker y = y % 3; 550*795d594fSAndroid Build Coastguard Worker hi = x.length; 551*795d594fSAndroid Build Coastguard Worker if (y != 123) break; 552*795d594fSAndroid Build Coastguard Worker } 553*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < hi; i++) { 554*795d594fSAndroid Build Coastguard Worker result += x[i]; 555*795d594fSAndroid Build Coastguard Worker } 556*795d594fSAndroid Build Coastguard Worker return result; 557*795d594fSAndroid Build Coastguard Worker } 558*795d594fSAndroid Build Coastguard Worker 559*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (before) 560*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 561*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 562*795d594fSAndroid Build Coastguard Worker // 563*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after) 564*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 565*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularOnTwoArrayLengths(int n)566*795d594fSAndroid Build Coastguard Worker private static void linearTriangularOnTwoArrayLengths(int n) { 567*795d594fSAndroid Build Coastguard Worker int[] a = new int[n]; 568*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 569*795d594fSAndroid Build Coastguard Worker int[] b = new int[i]; 570*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < b.length; j++) { 571*795d594fSAndroid Build Coastguard Worker // Need to know j < b.length < a.length for static bce. 572*795d594fSAndroid Build Coastguard Worker a[j] += 1; 573*795d594fSAndroid Build Coastguard Worker // Need to know just j < b.length for static bce. 574*795d594fSAndroid Build Coastguard Worker b[j] += 1; 575*795d594fSAndroid Build Coastguard Worker } 576*795d594fSAndroid Build Coastguard Worker verifyTriangular(a, b, i, n); 577*795d594fSAndroid Build Coastguard Worker } 578*795d594fSAndroid Build Coastguard Worker } 579*795d594fSAndroid Build Coastguard Worker 580*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (before) 581*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 582*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 583*795d594fSAndroid Build Coastguard Worker // 584*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (after) 585*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 586*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularOnOneArrayLength(int n)587*795d594fSAndroid Build Coastguard Worker private static void linearTriangularOnOneArrayLength(int n) { 588*795d594fSAndroid Build Coastguard Worker int[] a = new int[n]; 589*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 590*795d594fSAndroid Build Coastguard Worker int[] b = new int[i]; 591*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < i; j++) { 592*795d594fSAndroid Build Coastguard Worker // Need to know j < i < a.length for static bce. 593*795d594fSAndroid Build Coastguard Worker a[j] += 1; 594*795d594fSAndroid Build Coastguard Worker // Need to know just j < i for static bce. 595*795d594fSAndroid Build Coastguard Worker b[j] += 1; 596*795d594fSAndroid Build Coastguard Worker } 597*795d594fSAndroid Build Coastguard Worker verifyTriangular(a, b, i, n); 598*795d594fSAndroid Build Coastguard Worker } 599*795d594fSAndroid Build Coastguard Worker } 600*795d594fSAndroid Build Coastguard Worker 601*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (before) 602*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 603*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 604*795d594fSAndroid Build Coastguard Worker // 605*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after) 606*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 607*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularOnParameter(int n)608*795d594fSAndroid Build Coastguard Worker private static void linearTriangularOnParameter(int n) { 609*795d594fSAndroid Build Coastguard Worker int[] a = new int[n]; 610*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 611*795d594fSAndroid Build Coastguard Worker int[] b = new int[i]; 612*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < i; j++) { 613*795d594fSAndroid Build Coastguard Worker // Need to know j < i < n for static bce. 614*795d594fSAndroid Build Coastguard Worker a[j] += 1; 615*795d594fSAndroid Build Coastguard Worker // Need to know just j < i for static bce. 616*795d594fSAndroid Build Coastguard Worker b[j] += 1; 617*795d594fSAndroid Build Coastguard Worker } 618*795d594fSAndroid Build Coastguard Worker verifyTriangular(a, b, i, n); 619*795d594fSAndroid Build Coastguard Worker } 620*795d594fSAndroid Build Coastguard Worker } 621*795d594fSAndroid Build Coastguard Worker 622*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (before) 623*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 624*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 625*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 626*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 627*795d594fSAndroid Build Coastguard Worker // 628*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (after) 629*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 630*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularStrictLower(int n)631*795d594fSAndroid Build Coastguard Worker private static void linearTriangularStrictLower(int n) { 632*795d594fSAndroid Build Coastguard Worker int[] a = new int[n]; 633*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 634*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < i; j++) { 635*795d594fSAndroid Build Coastguard Worker a[j] += 1; 636*795d594fSAndroid Build Coastguard Worker } 637*795d594fSAndroid Build Coastguard Worker for (int j = i - 1; j >= 0; j--) { 638*795d594fSAndroid Build Coastguard Worker a[j] += 1; 639*795d594fSAndroid Build Coastguard Worker } 640*795d594fSAndroid Build Coastguard Worker for (int j = i; j < n; j++) { 641*795d594fSAndroid Build Coastguard Worker a[j] += 1; 642*795d594fSAndroid Build Coastguard Worker } 643*795d594fSAndroid Build Coastguard Worker for (int j = n - 1; j >= i; j--) { 644*795d594fSAndroid Build Coastguard Worker a[j] += 1; 645*795d594fSAndroid Build Coastguard Worker } 646*795d594fSAndroid Build Coastguard Worker } 647*795d594fSAndroid Build Coastguard Worker verifyTriangular(a); 648*795d594fSAndroid Build Coastguard Worker } 649*795d594fSAndroid Build Coastguard Worker 650*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (before) 651*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 652*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 653*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 654*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 655*795d594fSAndroid Build Coastguard Worker // 656*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (after) 657*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 658*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularStrictUpper(int n)659*795d594fSAndroid Build Coastguard Worker private static void linearTriangularStrictUpper(int n) { 660*795d594fSAndroid Build Coastguard Worker int[] a = new int[n]; 661*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 662*795d594fSAndroid Build Coastguard Worker for (int j = 0; j <= i; j++) { 663*795d594fSAndroid Build Coastguard Worker a[j] += 1; 664*795d594fSAndroid Build Coastguard Worker } 665*795d594fSAndroid Build Coastguard Worker for (int j = i; j >= 0; j--) { 666*795d594fSAndroid Build Coastguard Worker a[j] += 1; 667*795d594fSAndroid Build Coastguard Worker } 668*795d594fSAndroid Build Coastguard Worker for (int j = i + 1; j < n; j++) { 669*795d594fSAndroid Build Coastguard Worker a[j] += 1; 670*795d594fSAndroid Build Coastguard Worker } 671*795d594fSAndroid Build Coastguard Worker for (int j = n - 1; j >= i + 1; j--) { 672*795d594fSAndroid Build Coastguard Worker a[j] += 1; 673*795d594fSAndroid Build Coastguard Worker } 674*795d594fSAndroid Build Coastguard Worker } 675*795d594fSAndroid Build Coastguard Worker verifyTriangular(a); 676*795d594fSAndroid Build Coastguard Worker } 677*795d594fSAndroid Build Coastguard Worker 678*795d594fSAndroid Build Coastguard Worker // Verifier for triangular loops. verifyTriangular(int[] a, int[] b, int m, int n)679*795d594fSAndroid Build Coastguard Worker private static void verifyTriangular(int[] a, int[] b, int m, int n) { 680*795d594fSAndroid Build Coastguard Worker expectEquals(n, a.length); 681*795d594fSAndroid Build Coastguard Worker for (int i = 0, k = m; i < n; i++) { 682*795d594fSAndroid Build Coastguard Worker expectEquals(a[i], k); 683*795d594fSAndroid Build Coastguard Worker if (k > 0) k--; 684*795d594fSAndroid Build Coastguard Worker } 685*795d594fSAndroid Build Coastguard Worker expectEquals(m, b.length); 686*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < m; i++) { 687*795d594fSAndroid Build Coastguard Worker expectEquals(b[i], 1); 688*795d594fSAndroid Build Coastguard Worker } 689*795d594fSAndroid Build Coastguard Worker } 690*795d594fSAndroid Build Coastguard Worker 691*795d594fSAndroid Build Coastguard Worker // Verifier for triangular loops. verifyTriangular(int[] a)692*795d594fSAndroid Build Coastguard Worker private static void verifyTriangular(int[] a) { 693*795d594fSAndroid Build Coastguard Worker int n = a.length; 694*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 695*795d594fSAndroid Build Coastguard Worker expectEquals(a[i], n + n); 696*795d594fSAndroid Build Coastguard Worker } 697*795d594fSAndroid Build Coastguard Worker } 698*795d594fSAndroid Build Coastguard Worker 699*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearTriangularOOB() BCE (before) 700*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 701*795d594fSAndroid Build Coastguard Worker // 702*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after) 703*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 704*795d594fSAndroid Build Coastguard Worker // 705*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after) 706*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize linearTriangularOOB()707*795d594fSAndroid Build Coastguard Worker private static int[] linearTriangularOOB() { 708*795d594fSAndroid Build Coastguard Worker int[] a = new int[200]; 709*795d594fSAndroid Build Coastguard Worker try { 710*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 200; i++) { 711*795d594fSAndroid Build Coastguard Worker // Lower bound must be recognized as lower precision induction with arithmetic 712*795d594fSAndroid Build Coastguard Worker // wrap-around to -128 when i exceeds 127. 713*795d594fSAndroid Build Coastguard Worker for (int j = (byte) i; j < 200; j++) { 714*795d594fSAndroid Build Coastguard Worker a[j] += 1; 715*795d594fSAndroid Build Coastguard Worker } 716*795d594fSAndroid Build Coastguard Worker } 717*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 718*795d594fSAndroid Build Coastguard Worker return a; 719*795d594fSAndroid Build Coastguard Worker } 720*795d594fSAndroid Build Coastguard Worker return null; // failure if this is reached 721*795d594fSAndroid Build Coastguard Worker } 722*795d594fSAndroid Build Coastguard Worker 723*795d594fSAndroid Build Coastguard Worker // 724*795d594fSAndroid Build Coastguard Worker // Verifier. 725*795d594fSAndroid Build Coastguard Worker // 726*795d594fSAndroid Build Coastguard Worker main(String[] args)727*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 728*795d594fSAndroid Build Coastguard Worker int[] empty = { }; 729*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 730*795d594fSAndroid Build Coastguard Worker 731*795d594fSAndroid Build Coastguard Worker // Linear and wrap-around. 732*795d594fSAndroid Build Coastguard Worker expectEquals(0, linear(empty)); 733*795d594fSAndroid Build Coastguard Worker expectEquals(55, linear(x)); 734*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearDown(empty)); 735*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearDown(x)); 736*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearObscure(empty)); 737*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearObscure(x)); 738*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearVeryObscure(empty)); 739*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearVeryObscure(x)); 740*795d594fSAndroid Build Coastguard Worker expectEquals(0, hiddenStride(empty)); 741*795d594fSAndroid Build Coastguard Worker expectEquals(55, hiddenStride(x)); 742*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearWhile(empty)); 743*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearWhile(x)); 744*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearThreeWayPhi(empty)); 745*795d594fSAndroid Build Coastguard Worker expectEquals(50, linearThreeWayPhi(x)); 746*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearFourWayPhi(empty)); 747*795d594fSAndroid Build Coastguard Worker expectEquals(51, linearFourWayPhi(x)); 748*795d594fSAndroid Build Coastguard Worker expectEquals(0, wrapAroundThenLinear(empty)); 749*795d594fSAndroid Build Coastguard Worker expectEquals(55, wrapAroundThenLinear(x)); 750*795d594fSAndroid Build Coastguard Worker expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty)); 751*795d594fSAndroid Build Coastguard Worker expectEquals(54, wrapAroundThenLinearThreeWayPhi(x)); 752*795d594fSAndroid Build Coastguard Worker 753*795d594fSAndroid Build Coastguard Worker // Linear with parameter. 754*795d594fSAndroid Build Coastguard Worker sResult = 0; 755*795d594fSAndroid Build Coastguard Worker try { 756*795d594fSAndroid Build Coastguard Worker linearWithParameter(-1); 757*795d594fSAndroid Build Coastguard Worker } catch (NegativeArraySizeException e) { 758*795d594fSAndroid Build Coastguard Worker sResult = 1; 759*795d594fSAndroid Build Coastguard Worker } 760*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 761*795d594fSAndroid Build Coastguard Worker for (int n = 0; n < 32; n++) { 762*795d594fSAndroid Build Coastguard Worker int[] r = linearWithParameter(n); 763*795d594fSAndroid Build Coastguard Worker expectEquals(n, r.length); 764*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 765*795d594fSAndroid Build Coastguard Worker expectEquals(i, r[i]); 766*795d594fSAndroid Build Coastguard Worker } 767*795d594fSAndroid Build Coastguard Worker } 768*795d594fSAndroid Build Coastguard Worker 769*795d594fSAndroid Build Coastguard Worker // Linear copy. 770*795d594fSAndroid Build Coastguard Worker expectEquals(0, linearCopy(empty).length); 771*795d594fSAndroid Build Coastguard Worker { 772*795d594fSAndroid Build Coastguard Worker int[] r = linearCopy(x); 773*795d594fSAndroid Build Coastguard Worker expectEquals(x.length, r.length); 774*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 775*795d594fSAndroid Build Coastguard Worker expectEquals(x[i], r[i]); 776*795d594fSAndroid Build Coastguard Worker } 777*795d594fSAndroid Build Coastguard Worker } 778*795d594fSAndroid Build Coastguard Worker 779*795d594fSAndroid Build Coastguard Worker // Linear with non-unit strides. 780*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearByTwo(x)); 781*795d594fSAndroid Build Coastguard Worker expectEquals(25, linearByTwoSkip1(x)); 782*795d594fSAndroid Build Coastguard Worker expectEquals(25, linearByTwoSkip2(x)); 783*795d594fSAndroid Build Coastguard Worker expectEquals(56, linearWithCompoundStride()); 784*795d594fSAndroid Build Coastguard Worker expectEquals(66, linearWithLargePositiveStride()); 785*795d594fSAndroid Build Coastguard Worker expectEquals(66, linearWithVeryLargePositiveStride()); 786*795d594fSAndroid Build Coastguard Worker expectEquals(66, linearWithLargeNegativeStride()); 787*795d594fSAndroid Build Coastguard Worker expectEquals(66, linearWithVeryLargeNegativeStride()); 788*795d594fSAndroid Build Coastguard Worker 789*795d594fSAndroid Build Coastguard Worker // Special forms. 790*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearForNEUp()); 791*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearForNEDown()); 792*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearForNEArrayLengthUp(x)); 793*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearForNEArrayLengthDown(x)); 794*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearDoWhileUp()); 795*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearDoWhileDown()); 796*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearLong()); 797*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearLongAlt(x)); 798*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearShort()); 799*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearChar()); 800*795d594fSAndroid Build Coastguard Worker expectEquals(55, linearByte()); 801*795d594fSAndroid Build Coastguard Worker expectEquals(55, invariantFromPreLoop(x, 1)); 802*795d594fSAndroid Build Coastguard Worker linearTriangularOnTwoArrayLengths(10); 803*795d594fSAndroid Build Coastguard Worker linearTriangularOnOneArrayLength(10); 804*795d594fSAndroid Build Coastguard Worker linearTriangularOnParameter(10); 805*795d594fSAndroid Build Coastguard Worker linearTriangularStrictLower(10); 806*795d594fSAndroid Build Coastguard Worker linearTriangularStrictUpper(10); 807*795d594fSAndroid Build Coastguard Worker { 808*795d594fSAndroid Build Coastguard Worker int[] t = linearTriangularOOB(); 809*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 200; i++) { 810*795d594fSAndroid Build Coastguard Worker expectEquals(i <= 127 ? i + 1 : 128, t[i]); 811*795d594fSAndroid Build Coastguard Worker } 812*795d594fSAndroid Build Coastguard Worker } 813*795d594fSAndroid Build Coastguard Worker 814*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 815*795d594fSAndroid Build Coastguard Worker } 816*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)817*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 818*795d594fSAndroid Build Coastguard Worker if (expected != result) { 819*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 820*795d594fSAndroid Build Coastguard Worker } 821*795d594fSAndroid Build Coastguard Worker } 822*795d594fSAndroid Build Coastguard Worker } 823