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 less 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: void Main.bubble(int[]) BCE (before) 29*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 30*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 31*795d594fSAndroid Build Coastguard Worker // 32*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.bubble(int[]) BCE (after) 33*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 34*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize bubble(int[] a)35*795d594fSAndroid Build Coastguard Worker private static void bubble(int[] a) { 36*795d594fSAndroid Build Coastguard Worker for (int i = a.length; --i >= 0;) { 37*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < i; j++) { 38*795d594fSAndroid Build Coastguard Worker if (a[j] > a[j+1]) { 39*795d594fSAndroid Build Coastguard Worker int tmp = a[j]; 40*795d594fSAndroid Build Coastguard Worker a[j] = a[j+1]; 41*795d594fSAndroid Build Coastguard Worker a[j+1] = tmp; 42*795d594fSAndroid Build Coastguard Worker } 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicIdiom(int) BCE (before) 48*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 49*795d594fSAndroid Build Coastguard Worker // 50*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicIdiom(int) BCE (after) 51*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 52*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize periodicIdiom(int tc)53*795d594fSAndroid Build Coastguard Worker private static int periodicIdiom(int tc) { 54*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 3 }; 55*795d594fSAndroid Build Coastguard Worker // Loop with periodic sequence (0, 1). 56*795d594fSAndroid Build Coastguard Worker int k = 0; 57*795d594fSAndroid Build Coastguard Worker int result = 0; 58*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < tc; i++) { 59*795d594fSAndroid Build Coastguard Worker result += x[k]; 60*795d594fSAndroid Build Coastguard Worker k = 1 - k; 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker return result; 63*795d594fSAndroid Build Coastguard Worker } 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicSequence2(int) BCE (before) 66*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 67*795d594fSAndroid Build Coastguard Worker // 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicSequence2(int) BCE (after) 69*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 70*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize periodicSequence2(int tc)71*795d594fSAndroid Build Coastguard Worker private static int periodicSequence2(int tc) { 72*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 3 }; 73*795d594fSAndroid Build Coastguard Worker // Loop with periodic sequence (0, 1). 74*795d594fSAndroid Build Coastguard Worker int k = 0; 75*795d594fSAndroid Build Coastguard Worker int l = 1; 76*795d594fSAndroid Build Coastguard Worker int result = 0; 77*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < tc; i++) { 78*795d594fSAndroid Build Coastguard Worker result += x[k]; 79*795d594fSAndroid Build Coastguard Worker int t = l; 80*795d594fSAndroid Build Coastguard Worker l = k; 81*795d594fSAndroid Build Coastguard Worker k = t; 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.periodicSequence4(int) BCE (before) 87*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 88*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 89*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 90*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 91*795d594fSAndroid Build Coastguard Worker // 92*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicSequence4(int) BCE (after) 93*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 94*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize periodicSequence4(int tc)95*795d594fSAndroid Build Coastguard Worker private static int periodicSequence4(int tc) { 96*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 3, 5, 7 }; 97*795d594fSAndroid Build Coastguard Worker // Loop with periodic sequence (0, 1, 2, 3). 98*795d594fSAndroid Build Coastguard Worker int k = 0; 99*795d594fSAndroid Build Coastguard Worker int l = 1; 100*795d594fSAndroid Build Coastguard Worker int m = 2; 101*795d594fSAndroid Build Coastguard Worker int n = 3; 102*795d594fSAndroid Build Coastguard Worker int result = 0; 103*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < tc; i++) { 104*795d594fSAndroid Build Coastguard Worker result += x[k] + x[l] + x[m] + x[n]; // all used at once 105*795d594fSAndroid Build Coastguard Worker int t = n; 106*795d594fSAndroid Build Coastguard Worker n = k; 107*795d594fSAndroid Build Coastguard Worker k = l; 108*795d594fSAndroid Build Coastguard Worker l = m; 109*795d594fSAndroid Build Coastguard Worker m = t; 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker return result; 112*795d594fSAndroid Build Coastguard Worker } 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicXorSequence(int) BCE (before) 115*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 116*795d594fSAndroid Build Coastguard Worker // 117*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicXorSequence(int) BCE (after) 118*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 119*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize periodicXorSequence(int tc)120*795d594fSAndroid Build Coastguard Worker private static int periodicXorSequence(int tc) { 121*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 3 }; 122*795d594fSAndroid Build Coastguard Worker // Loop with periodic sequence (0, 1). 123*795d594fSAndroid Build Coastguard Worker int k = 0; 124*795d594fSAndroid Build Coastguard Worker int result = 0; 125*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < tc; i++) { 126*795d594fSAndroid Build Coastguard Worker result += x[k]; 127*795d594fSAndroid Build Coastguard Worker k ^= 1; 128*795d594fSAndroid Build Coastguard Worker } 129*795d594fSAndroid Build Coastguard Worker return result; 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp1() BCE (before) 133*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 134*795d594fSAndroid Build Coastguard Worker // 135*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp1() BCE (after) 136*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 137*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightUp1()138*795d594fSAndroid Build Coastguard Worker private static int justRightUp1() { 139*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 140*795d594fSAndroid Build Coastguard Worker int result = 0; 141*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) { 142*795d594fSAndroid Build Coastguard Worker result += x[k++]; 143*795d594fSAndroid Build Coastguard Worker } 144*795d594fSAndroid Build Coastguard Worker return result; 145*795d594fSAndroid Build Coastguard Worker } 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp2() BCE (before) 148*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 149*795d594fSAndroid Build Coastguard Worker // 150*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp2() BCE (after) 151*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 152*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightUp2()153*795d594fSAndroid Build Coastguard Worker private static int justRightUp2() { 154*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 155*795d594fSAndroid Build Coastguard Worker int result = 0; 156*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) { 157*795d594fSAndroid Build Coastguard Worker result += x[i - Integer.MAX_VALUE + 10]; 158*795d594fSAndroid Build Coastguard Worker } 159*795d594fSAndroid Build Coastguard Worker return result; 160*795d594fSAndroid Build Coastguard Worker } 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp3() BCE (before) 163*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 164*795d594fSAndroid Build Coastguard Worker // 165*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightUp3() BCE (after) 166*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 167*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightUp3()168*795d594fSAndroid Build Coastguard Worker private static int justRightUp3() { 169*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 170*795d594fSAndroid Build Coastguard Worker int result = 0; 171*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) { 172*795d594fSAndroid Build Coastguard Worker result += x[k++]; 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker return result; 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBUp() BCE (before) 178*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 179*795d594fSAndroid Build Coastguard Worker // 180*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBUp() BCE (after) 181*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 182*795d594fSAndroid Build Coastguard Worker // 183*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBUp() BCE (after) 184*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justOOBUp()185*795d594fSAndroid Build Coastguard Worker private static int justOOBUp() { 186*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 187*795d594fSAndroid Build Coastguard Worker int result = 0; 188*795d594fSAndroid Build Coastguard Worker // Infinite loop! 189*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) { 190*795d594fSAndroid Build Coastguard Worker result += x[k++]; 191*795d594fSAndroid Build Coastguard Worker } 192*795d594fSAndroid Build Coastguard Worker return result; 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker 195*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown1() BCE (before) 196*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 197*795d594fSAndroid Build Coastguard Worker // 198*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown1() BCE (after) 199*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 200*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightDown1()201*795d594fSAndroid Build Coastguard Worker private static int justRightDown1() { 202*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 203*795d594fSAndroid Build Coastguard Worker int result = 0; 204*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) { 205*795d594fSAndroid Build Coastguard Worker result += x[k++]; 206*795d594fSAndroid Build Coastguard Worker } 207*795d594fSAndroid Build Coastguard Worker return result; 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker 210*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown2() BCE (before) 211*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 212*795d594fSAndroid Build Coastguard Worker // 213*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown2() BCE (after) 214*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 215*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightDown2()216*795d594fSAndroid Build Coastguard Worker private static int justRightDown2() { 217*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 218*795d594fSAndroid Build Coastguard Worker int result = 0; 219*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) { 220*795d594fSAndroid Build Coastguard Worker result += x[Integer.MAX_VALUE + i]; 221*795d594fSAndroid Build Coastguard Worker } 222*795d594fSAndroid Build Coastguard Worker return result; 223*795d594fSAndroid Build Coastguard Worker } 224*795d594fSAndroid Build Coastguard Worker 225*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown3() BCE (before) 226*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 227*795d594fSAndroid Build Coastguard Worker // 228*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justRightDown3() BCE (after) 229*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 230*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightDown3()231*795d594fSAndroid Build Coastguard Worker private static int justRightDown3() { 232*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 233*795d594fSAndroid Build Coastguard Worker int result = 0; 234*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) { 235*795d594fSAndroid Build Coastguard Worker result += x[k++]; 236*795d594fSAndroid Build Coastguard Worker } 237*795d594fSAndroid Build Coastguard Worker return result; 238*795d594fSAndroid Build Coastguard Worker } 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBDown() BCE (before) 241*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 242*795d594fSAndroid Build Coastguard Worker // 243*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBDown() BCE (after) 244*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 245*795d594fSAndroid Build Coastguard Worker // 246*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.justOOBDown() BCE (after) 247*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justOOBDown()248*795d594fSAndroid Build Coastguard Worker private static int justOOBDown() { 249*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 250*795d594fSAndroid Build Coastguard Worker int result = 0; 251*795d594fSAndroid Build Coastguard Worker // Infinite loop! 252*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) { 253*795d594fSAndroid Build Coastguard Worker result += x[k++]; 254*795d594fSAndroid Build Coastguard Worker } 255*795d594fSAndroid Build Coastguard Worker return result; 256*795d594fSAndroid Build Coastguard Worker } 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.lowerOOB(int[]) BCE (before) 259*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 260*795d594fSAndroid Build Coastguard Worker // 261*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.lowerOOB(int[]) BCE (after) 262*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 263*795d594fSAndroid Build Coastguard Worker // 264*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.lowerOOB(int[]) BCE (after) 265*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize lowerOOB(int[] x)266*795d594fSAndroid Build Coastguard Worker private static void lowerOOB(int[] x) { 267*795d594fSAndroid Build Coastguard Worker // OOB! 268*795d594fSAndroid Build Coastguard Worker for (int i = -1; i < x.length; i++) { 269*795d594fSAndroid Build Coastguard Worker sResult += x[i]; 270*795d594fSAndroid Build Coastguard Worker } 271*795d594fSAndroid Build Coastguard Worker } 272*795d594fSAndroid Build Coastguard Worker 273*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.upperOOB(int[]) BCE (before) 274*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 275*795d594fSAndroid Build Coastguard Worker // 276*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.upperOOB(int[]) BCE (after) 277*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 278*795d594fSAndroid Build Coastguard Worker // 279*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.upperOOB(int[]) BCE (after) 280*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize upperOOB(int[] x)281*795d594fSAndroid Build Coastguard Worker private static void upperOOB(int[] x) { 282*795d594fSAndroid Build Coastguard Worker // OOB! 283*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= x.length; i++) { 284*795d594fSAndroid Build Coastguard Worker sResult += x[i]; 285*795d594fSAndroid Build Coastguard Worker } 286*795d594fSAndroid Build Coastguard Worker } 287*795d594fSAndroid Build Coastguard Worker 288*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileUpOOB() BCE (before) 289*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 290*795d594fSAndroid Build Coastguard Worker // 291*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileUpOOB() BCE (after) 292*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 293*795d594fSAndroid Build Coastguard Worker // 294*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileUpOOB() BCE (after) 295*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize doWhileUpOOB()296*795d594fSAndroid Build Coastguard Worker private static void doWhileUpOOB() { 297*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 298*795d594fSAndroid Build Coastguard Worker int i = 0; 299*795d594fSAndroid Build Coastguard Worker // OOB! 300*795d594fSAndroid Build Coastguard Worker do { 301*795d594fSAndroid Build Coastguard Worker sResult += x[i++]; 302*795d594fSAndroid Build Coastguard Worker } while (i <= x.length); 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker 305*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileDownOOB() BCE (before) 306*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 307*795d594fSAndroid Build Coastguard Worker // 308*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileDownOOB() BCE (after) 309*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 310*795d594fSAndroid Build Coastguard Worker // 311*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.doWhileDownOOB() BCE (after) 312*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize doWhileDownOOB()313*795d594fSAndroid Build Coastguard Worker private static void doWhileDownOOB() { 314*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 315*795d594fSAndroid Build Coastguard Worker int i = x.length - 1; 316*795d594fSAndroid Build Coastguard Worker // OOB! 317*795d594fSAndroid Build Coastguard Worker do { 318*795d594fSAndroid Build Coastguard Worker sResult += x[i--]; 319*795d594fSAndroid Build Coastguard Worker } while (-1 <= i); 320*795d594fSAndroid Build Coastguard Worker } 321*795d594fSAndroid Build Coastguard Worker 322*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justRightTriangular1() BCE (before) 323*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 324*795d594fSAndroid Build Coastguard Worker // 325*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justRightTriangular1() BCE (after) 326*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 327*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightTriangular1()328*795d594fSAndroid Build Coastguard Worker private static void justRightTriangular1() { 329*795d594fSAndroid Build Coastguard Worker int[] a = { 1 } ; 330*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 5; i <= Integer.MIN_VALUE + 10; i++) { 331*795d594fSAndroid Build Coastguard Worker for (int j = Integer.MIN_VALUE + 4; j < i - 5; j++) { 332*795d594fSAndroid Build Coastguard Worker sResult += a[j - (Integer.MIN_VALUE + 4)]; 333*795d594fSAndroid Build Coastguard Worker } 334*795d594fSAndroid Build Coastguard Worker } 335*795d594fSAndroid Build Coastguard Worker } 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justRightTriangular2() BCE (before) 338*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 339*795d594fSAndroid Build Coastguard Worker // 340*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justRightTriangular2() BCE (after) 341*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 342*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize justRightTriangular2()343*795d594fSAndroid Build Coastguard Worker private static void justRightTriangular2() { 344*795d594fSAndroid Build Coastguard Worker int[] a = { 1 } ; 345*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 5; i <= 10; i++) { 346*795d594fSAndroid Build Coastguard Worker for (int j = 4; j < i - 5; j++) { 347*795d594fSAndroid Build Coastguard Worker sResult += a[j - 4]; 348*795d594fSAndroid Build Coastguard Worker } 349*795d594fSAndroid Build Coastguard Worker } 350*795d594fSAndroid Build Coastguard Worker } 351*795d594fSAndroid Build Coastguard Worker 352*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justOOBTriangular() BCE (before) 353*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 354*795d594fSAndroid Build Coastguard Worker // 355*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justOOBTriangular() BCE (after) 356*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize 357*795d594fSAndroid Build Coastguard Worker // 358*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.justOOBTriangular() BCE (after) 359*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck justOOBTriangular()360*795d594fSAndroid Build Coastguard Worker private static void justOOBTriangular() { 361*795d594fSAndroid Build Coastguard Worker int[] a = { 1 } ; 362*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE + 4; i <= 10; i++) { 363*795d594fSAndroid Build Coastguard Worker for (int j = 4; j < i - 5; j++) { 364*795d594fSAndroid Build Coastguard Worker sResult += a[j - 4]; 365*795d594fSAndroid Build Coastguard Worker } 366*795d594fSAndroid Build Coastguard Worker } 367*795d594fSAndroid Build Coastguard Worker } 368*795d594fSAndroid Build Coastguard Worker 369*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB1(int) BCE (before) 370*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 371*795d594fSAndroid Build Coastguard Worker // 372*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB1(int) BCE (after) 373*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize 374*795d594fSAndroid Build Coastguard Worker // 375*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB1(int) BCE (after) 376*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck hiddenOOB1(int lo)377*795d594fSAndroid Build Coastguard Worker private static void hiddenOOB1(int lo) { 378*795d594fSAndroid Build Coastguard Worker int[] a = { 1 } ; 379*795d594fSAndroid Build Coastguard Worker for (int i = lo; i <= 10; i++) { 380*795d594fSAndroid Build Coastguard Worker // Dangerous loop where careless static range analysis would yield strict upper bound 381*795d594fSAndroid Build Coastguard Worker // on index j of 5. When, for instance, lo and thus i = -2147483648, the upper bound 382*795d594fSAndroid Build Coastguard Worker // becomes really positive due to arithmetic wrap-around, causing OOB. 383*795d594fSAndroid Build Coastguard Worker for (int j = 4; j < i - 5; j++) { 384*795d594fSAndroid Build Coastguard Worker sResult += a[j - 4]; 385*795d594fSAndroid Build Coastguard Worker } 386*795d594fSAndroid Build Coastguard Worker } 387*795d594fSAndroid Build Coastguard Worker } 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB2(int) BCE (before) 390*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 391*795d594fSAndroid Build Coastguard Worker // 392*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB2(int) BCE (after) 393*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize 394*795d594fSAndroid Build Coastguard Worker // 395*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB2(int) BCE (after) 396*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck hiddenOOB2(int hi)397*795d594fSAndroid Build Coastguard Worker private static void hiddenOOB2(int hi) { 398*795d594fSAndroid Build Coastguard Worker int[] a = { 1 } ; 399*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < hi; i++) { 400*795d594fSAndroid Build Coastguard Worker // Dangerous loop where careless static range analysis would yield strict lower bound 401*795d594fSAndroid Build Coastguard Worker // on index j of 5. When, for instance, hi and thus i = 2147483647, the upper bound 402*795d594fSAndroid Build Coastguard Worker // becomes really negative due to arithmetic wrap-around, causing OOB. 403*795d594fSAndroid Build Coastguard Worker for (int j = 6; j > i + 5; j--) { 404*795d594fSAndroid Build Coastguard Worker sResult += a[j - 6]; 405*795d594fSAndroid Build Coastguard Worker } 406*795d594fSAndroid Build Coastguard Worker } 407*795d594fSAndroid Build Coastguard Worker } 408*795d594fSAndroid Build Coastguard Worker 409*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB3(int) BCE (before) 410*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 411*795d594fSAndroid Build Coastguard Worker // 412*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB3(int) BCE (after) 413*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize 414*795d594fSAndroid Build Coastguard Worker // 415*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenOOB3(int) BCE (after) 416*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck hiddenOOB3(int hi)417*795d594fSAndroid Build Coastguard Worker private static void hiddenOOB3(int hi) { 418*795d594fSAndroid Build Coastguard Worker int[] a = { 11 } ; 419*795d594fSAndroid Build Coastguard Worker for (int i = -1; i <= hi; i++) { 420*795d594fSAndroid Build Coastguard Worker // Dangerous loop where careless static range analysis would yield strict lower bound 421*795d594fSAndroid Build Coastguard Worker // on index j of 0. For large i, the initial value of j becomes really negative due 422*795d594fSAndroid Build Coastguard Worker // to arithmetic wrap-around, causing OOB. 423*795d594fSAndroid Build Coastguard Worker for (int j = i + 1; j < 1; j++) { 424*795d594fSAndroid Build Coastguard Worker sResult += a[j]; 425*795d594fSAndroid Build Coastguard Worker } 426*795d594fSAndroid Build Coastguard Worker } 427*795d594fSAndroid Build Coastguard Worker } 428*795d594fSAndroid Build Coastguard Worker 429*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (before) 430*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 431*795d594fSAndroid Build Coastguard Worker // 432*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (after) 433*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 434*795d594fSAndroid Build Coastguard Worker // 435*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (after) 436*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize hiddenInfiniteOOB()437*795d594fSAndroid Build Coastguard Worker private static void hiddenInfiniteOOB() { 438*795d594fSAndroid Build Coastguard Worker int[] a = { 11 } ; 439*795d594fSAndroid Build Coastguard Worker for (int i = -1; i <= 0; i++) { 440*795d594fSAndroid Build Coastguard Worker // Dangerous loop where careless static range analysis would yield a safe upper bound 441*795d594fSAndroid Build Coastguard Worker // of -3. In reality, due to arithmetic wrap-around (when i = -1, j <= 2147483647; 442*795d594fSAndroid Build Coastguard Worker // whereas when i = 0, j <= -3), this is an infinite loop that goes OOB. 443*795d594fSAndroid Build Coastguard Worker for (int j = -3; j <= 2147483646 * i - 3; j++) { 444*795d594fSAndroid Build Coastguard Worker sResult += a[j + 3]; 445*795d594fSAndroid Build Coastguard Worker } 446*795d594fSAndroid Build Coastguard Worker } 447*795d594fSAndroid Build Coastguard Worker } 448*795d594fSAndroid Build Coastguard Worker 449*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenFiniteOOB() BCE (before) 450*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 451*795d594fSAndroid Build Coastguard Worker // 452*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenFiniteOOB() BCE (after) 453*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize 454*795d594fSAndroid Build Coastguard Worker // 455*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.hiddenFiniteOOB() BCE (after) 456*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck hiddenFiniteOOB()457*795d594fSAndroid Build Coastguard Worker private static void hiddenFiniteOOB() { 458*795d594fSAndroid Build Coastguard Worker int[] a = { 111 } ; 459*795d594fSAndroid Build Coastguard Worker for (int i = -1; i <= 0; i++) { 460*795d594fSAndroid Build Coastguard Worker // Dangerous loop similar as above where the loop is now finite, but the 461*795d594fSAndroid Build Coastguard Worker // loop still goes out of bounds for i = -1 due to the large upper bound. 462*795d594fSAndroid Build Coastguard Worker for (int j = -4; j < 2147483646 * i - 3; j++) { 463*795d594fSAndroid Build Coastguard Worker sResult += a[j + 4]; 464*795d594fSAndroid Build Coastguard Worker } 465*795d594fSAndroid Build Coastguard Worker } 466*795d594fSAndroid Build Coastguard Worker } 467*795d594fSAndroid Build Coastguard Worker 468*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inductionOOB(int[]) BCE (before) 469*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 470*795d594fSAndroid Build Coastguard Worker // 471*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inductionOOB(int[]) BCE (after) 472*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 473*795d594fSAndroid Build Coastguard Worker // 474*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inductionOOB(int[]) BCE (after) 475*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize inductionOOB(int[] a)476*795d594fSAndroid Build Coastguard Worker private static void inductionOOB(int[] a) { 477*795d594fSAndroid Build Coastguard Worker // Careless range analysis would remove the bounds check. 478*795d594fSAndroid Build Coastguard Worker // However, the narrower induction b wraps around arithmetically 479*795d594fSAndroid Build Coastguard Worker // before it reaches the end of arrays longer than 127. 480*795d594fSAndroid Build Coastguard Worker byte b = 0; 481*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 482*795d594fSAndroid Build Coastguard Worker a[b++] = i; 483*795d594fSAndroid Build Coastguard Worker } 484*795d594fSAndroid Build Coastguard Worker } 485*795d594fSAndroid Build Coastguard Worker 486*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.controlOOB(int[]) BCE (before) 487*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 488*795d594fSAndroid Build Coastguard Worker // 489*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.controlOOB(int[]) BCE (after) 490*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 491*795d594fSAndroid Build Coastguard Worker // 492*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.controlOOB(int[]) BCE (after) 493*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize controlOOB(int[] a)494*795d594fSAndroid Build Coastguard Worker private static void controlOOB(int[] a) { 495*795d594fSAndroid Build Coastguard Worker // As above, but now the loop control also wraps around. 496*795d594fSAndroid Build Coastguard Worker for (byte i = 0; i < a.length; i++) { 497*795d594fSAndroid Build Coastguard Worker a[i] = -i; 498*795d594fSAndroid Build Coastguard Worker } 499*795d594fSAndroid Build Coastguard Worker } 500*795d594fSAndroid Build Coastguard Worker 501*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.conversionOOB(int[]) BCE (before) 502*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 503*795d594fSAndroid Build Coastguard Worker // 504*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.conversionOOB(int[]) BCE (after) 505*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 506*795d594fSAndroid Build Coastguard Worker // 507*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.conversionOOB(int[]) BCE (after) 508*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize conversionOOB(int[] a)509*795d594fSAndroid Build Coastguard Worker private static void conversionOOB(int[] a) { 510*795d594fSAndroid Build Coastguard Worker // As above, but with wrap around caused by an explicit conversion. 511*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; ) { 512*795d594fSAndroid Build Coastguard Worker a[i] = i; 513*795d594fSAndroid Build Coastguard Worker i = (byte) (i + 1); 514*795d594fSAndroid Build Coastguard Worker } 515*795d594fSAndroid Build Coastguard Worker } 516*795d594fSAndroid Build Coastguard Worker 517*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doNotHoist(int[]) BCE (before) 518*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 519*795d594fSAndroid Build Coastguard Worker // 520*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doNotHoist(int[]) BCE (after) 521*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck doNotHoist(int[] a)522*795d594fSAndroid Build Coastguard Worker public static int doNotHoist(int[] a) { 523*795d594fSAndroid Build Coastguard Worker int n = a.length; 524*795d594fSAndroid Build Coastguard Worker int x = 0; 525*795d594fSAndroid Build Coastguard Worker // BCE applies, but hoisting would crash the loop. 526*795d594fSAndroid Build Coastguard Worker for (int i = -10000; i < 10000; i++) { 527*795d594fSAndroid Build Coastguard Worker for (int j = 0; j <= 1; j++) { 528*795d594fSAndroid Build Coastguard Worker if (0 <= i && i < n) 529*795d594fSAndroid Build Coastguard Worker x += a[i]; 530*795d594fSAndroid Build Coastguard Worker } 531*795d594fSAndroid Build Coastguard Worker } 532*795d594fSAndroid Build Coastguard Worker return x; 533*795d594fSAndroid Build Coastguard Worker } 534*795d594fSAndroid Build Coastguard Worker 535*795d594fSAndroid Build Coastguard Worker 536*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.add() BCE (before) 537*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 538*795d594fSAndroid Build Coastguard Worker // 539*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.add() BCE (after) 540*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 541*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize add()542*795d594fSAndroid Build Coastguard Worker private static int[] add() { 543*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 544*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= 3; i++) { 545*795d594fSAndroid Build Coastguard Worker for (int j = 0; j <= 6; j++) { 546*795d594fSAndroid Build Coastguard Worker a[i + j] += 1; 547*795d594fSAndroid Build Coastguard Worker } 548*795d594fSAndroid Build Coastguard Worker } 549*795d594fSAndroid Build Coastguard Worker return a; 550*795d594fSAndroid Build Coastguard Worker } 551*795d594fSAndroid Build Coastguard Worker 552*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.multiply1() BCE (before) 553*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 554*795d594fSAndroid Build Coastguard Worker // 555*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.multiply1() BCE (after) 556*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 557*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize multiply1()558*795d594fSAndroid Build Coastguard Worker private static int[] multiply1() { 559*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 560*795d594fSAndroid Build Coastguard Worker try { 561*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= 3; i++) { 562*795d594fSAndroid Build Coastguard Worker for (int j = 0; j <= 3; j++) { 563*795d594fSAndroid Build Coastguard Worker // Range [0,9]: safe. 564*795d594fSAndroid Build Coastguard Worker a[i * j] += 1; 565*795d594fSAndroid Build Coastguard Worker } 566*795d594fSAndroid Build Coastguard Worker } 567*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 568*795d594fSAndroid Build Coastguard Worker a[0] += 1000; 569*795d594fSAndroid Build Coastguard Worker } 570*795d594fSAndroid Build Coastguard Worker return a; 571*795d594fSAndroid Build Coastguard Worker } 572*795d594fSAndroid Build Coastguard Worker 573*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.multiply2() BCE (before) 574*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 575*795d594fSAndroid Build Coastguard Worker // 576*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.multiply2() BCE (after) 577*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck 578*795d594fSAndroid Build Coastguard Worker // 579*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int[] Main.multiply2() BCE (after) 580*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize multiply2()581*795d594fSAndroid Build Coastguard Worker static int[] multiply2() { 582*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 583*795d594fSAndroid Build Coastguard Worker try { 584*795d594fSAndroid Build Coastguard Worker for (int i = -3; i <= 3; i++) { 585*795d594fSAndroid Build Coastguard Worker for (int j = -3; j <= 3; j++) { 586*795d594fSAndroid Build Coastguard Worker // Range [-9,9]: unsafe. 587*795d594fSAndroid Build Coastguard Worker a[i * j] += 1; 588*795d594fSAndroid Build Coastguard Worker } 589*795d594fSAndroid Build Coastguard Worker } 590*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 591*795d594fSAndroid Build Coastguard Worker a[0] += 1000; 592*795d594fSAndroid Build Coastguard Worker } 593*795d594fSAndroid Build Coastguard Worker return a; 594*795d594fSAndroid Build Coastguard Worker } 595*795d594fSAndroid Build Coastguard Worker 596*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (before) 597*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 598*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 599*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 600*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 601*795d594fSAndroid Build Coastguard Worker // 602*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after) 603*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:{{B\d+}} 604*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 605*795d594fSAndroid Build Coastguard Worker // 606*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after) 607*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 608*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 609*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} linearDynamicBCE1(int[] x, int lo, int hi)610*795d594fSAndroid Build Coastguard Worker private static int linearDynamicBCE1(int[] x, int lo, int hi) { 611*795d594fSAndroid Build Coastguard Worker int result = 0; 612*795d594fSAndroid Build Coastguard Worker for (int i = lo; i < hi; i++) { 613*795d594fSAndroid Build Coastguard Worker sResult += x[i]; 614*795d594fSAndroid Build Coastguard Worker } 615*795d594fSAndroid Build Coastguard Worker return result; 616*795d594fSAndroid Build Coastguard Worker } 617*795d594fSAndroid Build Coastguard Worker 618*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (before) 619*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 620*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 621*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 622*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 623*795d594fSAndroid Build Coastguard Worker // 624*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after) 625*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:{{B\d+}} 626*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 627*795d594fSAndroid Build Coastguard Worker // 628*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after) 629*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 630*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 631*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} linearDynamicBCE2(int[] x, int lo, int hi, int offset)632*795d594fSAndroid Build Coastguard Worker private static int linearDynamicBCE2(int[] x, int lo, int hi, int offset) { 633*795d594fSAndroid Build Coastguard Worker int result = 0; 634*795d594fSAndroid Build Coastguard Worker for (int i = lo; i < hi; i++) { 635*795d594fSAndroid Build Coastguard Worker sResult += x[offset + i]; 636*795d594fSAndroid Build Coastguard Worker } 637*795d594fSAndroid Build Coastguard Worker return result; 638*795d594fSAndroid Build Coastguard Worker } 639*795d594fSAndroid Build Coastguard Worker 640*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (before) 641*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 642*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 643*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 644*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 645*795d594fSAndroid Build Coastguard Worker // 646*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after) 647*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:{{B\d+}} 648*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 649*795d594fSAndroid Build Coastguard Worker // 650*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after) 651*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 652*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 653*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} wrapAroundDynamicBCE(int[] x)654*795d594fSAndroid Build Coastguard Worker private static int wrapAroundDynamicBCE(int[] x) { 655*795d594fSAndroid Build Coastguard Worker int w = 9; 656*795d594fSAndroid Build Coastguard Worker int result = 0; 657*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 658*795d594fSAndroid Build Coastguard Worker result += x[w]; 659*795d594fSAndroid Build Coastguard Worker w = i; 660*795d594fSAndroid Build Coastguard Worker } 661*795d594fSAndroid Build Coastguard Worker return result; 662*795d594fSAndroid Build Coastguard Worker } 663*795d594fSAndroid Build Coastguard Worker 664*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (before) 665*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 666*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 667*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 668*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 669*795d594fSAndroid Build Coastguard Worker // 670*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after) 671*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:{{B\d+}} 672*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 673*795d594fSAndroid Build Coastguard Worker // 674*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after) 675*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 676*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 677*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} periodicDynamicBCE(int[] x)678*795d594fSAndroid Build Coastguard Worker private static int periodicDynamicBCE(int[] x) { 679*795d594fSAndroid Build Coastguard Worker int k = 0; 680*795d594fSAndroid Build Coastguard Worker int result = 0; 681*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 682*795d594fSAndroid Build Coastguard Worker result += x[k]; 683*795d594fSAndroid Build Coastguard Worker k = 1 - k; 684*795d594fSAndroid Build Coastguard Worker } 685*795d594fSAndroid Build Coastguard Worker return result; 686*795d594fSAndroid Build Coastguard Worker } 687*795d594fSAndroid Build Coastguard Worker 688*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before) 689*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 690*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 691*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 692*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 693*795d594fSAndroid Build Coastguard Worker // 694*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after) 695*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:{{B\d+}} 696*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 697*795d594fSAndroid Build Coastguard Worker // 698*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after) 699*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 700*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 701*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi)702*795d594fSAndroid Build Coastguard Worker static int dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) { 703*795d594fSAndroid Build Coastguard Worker // This loop could be infinite for hi = max int. Since i is also used 704*795d594fSAndroid Build Coastguard Worker // as subscript, however, dynamic bce can proceed. 705*795d594fSAndroid Build Coastguard Worker int result = 0; 706*795d594fSAndroid Build Coastguard Worker for (int i = lo; i <= hi; i++) { 707*795d594fSAndroid Build Coastguard Worker result += x[i]; 708*795d594fSAndroid Build Coastguard Worker } 709*795d594fSAndroid Build Coastguard Worker return result; 710*795d594fSAndroid Build Coastguard Worker } 711*795d594fSAndroid Build Coastguard Worker 712*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before) 713*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 714*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 715*795d594fSAndroid Build Coastguard Worker // 716*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after) 717*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 718*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 719*795d594fSAndroid Build Coastguard Worker // 720*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after) 721*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi)722*795d594fSAndroid Build Coastguard Worker static int noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) { 723*795d594fSAndroid Build Coastguard Worker // As above, but now the index is not used as subscript, 724*795d594fSAndroid Build Coastguard Worker // and dynamic bce is not applied. 725*795d594fSAndroid Build Coastguard Worker int result = 0; 726*795d594fSAndroid Build Coastguard Worker for (int k = 0, i = lo; i <= hi; i++) { 727*795d594fSAndroid Build Coastguard Worker result += x[k++]; 728*795d594fSAndroid Build Coastguard Worker } 729*795d594fSAndroid Build Coastguard Worker return result; 730*795d594fSAndroid Build Coastguard Worker } 731*795d594fSAndroid Build Coastguard Worker 732*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (before) 733*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 734*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 735*795d594fSAndroid Build Coastguard Worker // 736*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after) 737*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 738*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 739*795d594fSAndroid Build Coastguard Worker // 740*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after) 741*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi)742*795d594fSAndroid Build Coastguard Worker static int noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi) { 743*795d594fSAndroid Build Coastguard Worker int result = 0; 744*795d594fSAndroid Build Coastguard Worker // Mix of int and long induction. 745*795d594fSAndroid Build Coastguard Worker int k = 0; 746*795d594fSAndroid Build Coastguard Worker for (long i = lo; i < hi; i++) { 747*795d594fSAndroid Build Coastguard Worker result += x[k++]; 748*795d594fSAndroid Build Coastguard Worker } 749*795d594fSAndroid Build Coastguard Worker return result; 750*795d594fSAndroid Build Coastguard Worker } 751*795d594fSAndroid Build Coastguard Worker 752*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (before) 753*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<InnerLoop:B\d+>> 754*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<InnerLoop>> 755*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If loop:<<InnerLoop>> 756*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If loop:<<OuterLoop:B\d+>> 757*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>" 758*795d594fSAndroid Build Coastguard Worker // 759*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after) 760*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<InnerLoop:B\d+>> 761*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>> 762*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>" 763*795d594fSAndroid Build Coastguard Worker // 764*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after) 765*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 766*795d594fSAndroid Build Coastguard Worker // 767*795d594fSAndroid Build Coastguard Worker // No additional top tests were introduced. 768*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after) 769*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 770*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: If 771*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: If dynamicBCEConstantRange(int[] x)772*795d594fSAndroid Build Coastguard Worker static int dynamicBCEConstantRange(int[] x) { 773*795d594fSAndroid Build Coastguard Worker int result = 0; 774*795d594fSAndroid Build Coastguard Worker for (int i = 2; i <= 6; i++) { 775*795d594fSAndroid Build Coastguard Worker // Range analysis sees that innermost loop is finite and always taken. 776*795d594fSAndroid Build Coastguard Worker for (int j = i - 2; j <= i + 2; j++) { 777*795d594fSAndroid Build Coastguard Worker result += x[j]; 778*795d594fSAndroid Build Coastguard Worker } 779*795d594fSAndroid Build Coastguard Worker } 780*795d594fSAndroid Build Coastguard Worker return result; 781*795d594fSAndroid Build Coastguard Worker } 782*795d594fSAndroid Build Coastguard Worker 783*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (before) 784*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop:B\d+>> 785*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>> 786*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>> 787*795d594fSAndroid Build Coastguard Worker // 788*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after) 789*795d594fSAndroid Build Coastguard Worker // Order matters: 790*795d594fSAndroid Build Coastguard Worker /// CHECK: Deoptimize loop:<<Loop:B\d+>> 791*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Goto loop:<<Loop>> 792*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>> 793*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>> 794*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>> 795*795d594fSAndroid Build Coastguard Worker /// CHECK: Goto loop:<<Loop>> 796*795d594fSAndroid Build Coastguard Worker // 797*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after) 798*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi)799*795d594fSAndroid Build Coastguard Worker static int dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi) { 800*795d594fSAndroid Build Coastguard Worker // Deliberately test array length on a before the loop so that only bounds checks 801*795d594fSAndroid Build Coastguard Worker // on constant subscripts remain, making them a viable candidate for hoisting. 802*795d594fSAndroid Build Coastguard Worker if (a.length == 0) { 803*795d594fSAndroid Build Coastguard Worker return -1; 804*795d594fSAndroid Build Coastguard Worker } 805*795d594fSAndroid Build Coastguard Worker // Loop that allows BCE on x[i]. 806*795d594fSAndroid Build Coastguard Worker int result = 0; 807*795d594fSAndroid Build Coastguard Worker for (int i = lo; i < hi; i++) { 808*795d594fSAndroid Build Coastguard Worker result += x[i]; 809*795d594fSAndroid Build Coastguard Worker if ((i % 10) != 0) { 810*795d594fSAndroid Build Coastguard Worker // None of the subscripts inside a conditional are removed by dynamic bce, 811*795d594fSAndroid Build Coastguard Worker // making them a candidate for deoptimization based on constant indices. 812*795d594fSAndroid Build Coastguard Worker // Compiler should ensure the array loads are not subsequently hoisted 813*795d594fSAndroid Build Coastguard Worker // "above" the deoptimization "barrier" on the bounds. 814*795d594fSAndroid Build Coastguard Worker a[1][i] = 1; 815*795d594fSAndroid Build Coastguard Worker a[2][i] = 2; 816*795d594fSAndroid Build Coastguard Worker a[99][i] = 3; 817*795d594fSAndroid Build Coastguard Worker } 818*795d594fSAndroid Build Coastguard Worker } 819*795d594fSAndroid Build Coastguard Worker return result; 820*795d594fSAndroid Build Coastguard Worker } 821*795d594fSAndroid Build Coastguard Worker 822*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (before) 823*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 824*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 825*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 826*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 827*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 828*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 829*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 830*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 831*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 832*795d594fSAndroid Build Coastguard Worker // For brevity, just test occurrence of at least one of each in the loop: 833*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 834*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 835*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 836*795d594fSAndroid Build Coastguard Worker // 837*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after) 838*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 839*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayGet loop:<<Loop>> 840*795d594fSAndroid Build Coastguard Worker // 841*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after) 842*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: NullCheck loop:{{B\d+}} 843*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 844*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} 845*795d594fSAndroid Build Coastguard Worker // 846*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after) 847*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none dynamicBCEAndConstantIndicesAllPrimTypes(int[] q, boolean[] r, byte[] s, char[] t, short[] u, int[] v, long[] w, float[] x, double[] y, int lo, int hi)848*795d594fSAndroid Build Coastguard Worker static int dynamicBCEAndConstantIndicesAllPrimTypes(int[] q, 849*795d594fSAndroid Build Coastguard Worker boolean[] r, 850*795d594fSAndroid Build Coastguard Worker byte[] s, 851*795d594fSAndroid Build Coastguard Worker char[] t, 852*795d594fSAndroid Build Coastguard Worker short[] u, 853*795d594fSAndroid Build Coastguard Worker int[] v, 854*795d594fSAndroid Build Coastguard Worker long[] w, 855*795d594fSAndroid Build Coastguard Worker float[] x, 856*795d594fSAndroid Build Coastguard Worker double[] y, int lo, int hi) { 857*795d594fSAndroid Build Coastguard Worker int result = 0; 858*795d594fSAndroid Build Coastguard Worker for (int i = lo; i < hi; i++) { 859*795d594fSAndroid Build Coastguard Worker // All constant index array references can be hoisted out of the loop during BCE on q[i]. 860*795d594fSAndroid Build Coastguard Worker result += q[i] + (r[0] ? 1 : 0) + (int) s[0] + (int) t[0] + (int) u[0] + (int) v[0] + 861*795d594fSAndroid Build Coastguard Worker (int) w[0] + (int) x[0] + (int) y[0]; 862*795d594fSAndroid Build Coastguard Worker } 863*795d594fSAndroid Build Coastguard Worker return result; 864*795d594fSAndroid Build Coastguard Worker } 865*795d594fSAndroid Build Coastguard Worker 866*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (before) 867*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 868*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 869*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 870*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 871*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> 872*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: NullCheck loop:<<Loop>> 873*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayLength loop:<<Loop>> 874*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 875*795d594fSAndroid Build Coastguard Worker // 876*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after) 877*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> 878*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 879*795d594fSAndroid Build Coastguard Worker // 880*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after) 881*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayLength loop:{{B\d+}} 882*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:{{B\d+}} dynamicBCEAndConstantIndexRefType(int[] q, Integer[] z, int lo, int hi)883*795d594fSAndroid Build Coastguard Worker static int dynamicBCEAndConstantIndexRefType(int[] q, Integer[] z, int lo, int hi) { 884*795d594fSAndroid Build Coastguard Worker int result = 0; 885*795d594fSAndroid Build Coastguard Worker for (int i = lo; i < hi; i++) { 886*795d594fSAndroid Build Coastguard Worker // Similar to above, but now implicit call to intValue() may prevent hoisting 887*795d594fSAndroid Build Coastguard Worker // z[0] itself during BCE on q[i]. Therefore, we just check BCE on q[i]. 888*795d594fSAndroid Build Coastguard Worker result += q[i] + z[0]; 889*795d594fSAndroid Build Coastguard Worker } 890*795d594fSAndroid Build Coastguard Worker return result; 891*795d594fSAndroid Build Coastguard Worker } 892*795d594fSAndroid Build Coastguard Worker 893*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.shortIndex(int[]) BCE (before) 894*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 895*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 896*795d594fSAndroid Build Coastguard Worker // 897*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.shortIndex(int[]) BCE (after) 898*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 899*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 900*795d594fSAndroid Build Coastguard Worker // 901*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.shortIndex(int[]) BCE (after) 902*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize shortIndex(int[] a)903*795d594fSAndroid Build Coastguard Worker static int shortIndex(int[] a) { 904*795d594fSAndroid Build Coastguard Worker int r = 0; 905*795d594fSAndroid Build Coastguard Worker // Make sure short/int conversions compiles well (b/32193474). 906*795d594fSAndroid Build Coastguard Worker for (short i = 1; i < 10; i++) { 907*795d594fSAndroid Build Coastguard Worker int ki = i - 1; 908*795d594fSAndroid Build Coastguard Worker r += a[ki] + a[i]; 909*795d594fSAndroid Build Coastguard Worker } 910*795d594fSAndroid Build Coastguard Worker return r; 911*795d594fSAndroid Build Coastguard Worker } 912*795d594fSAndroid Build Coastguard Worker 913*795d594fSAndroid Build Coastguard Worker // 914*795d594fSAndroid Build Coastguard Worker // Verifier. 915*795d594fSAndroid Build Coastguard Worker // 916*795d594fSAndroid Build Coastguard Worker main(String[] args)917*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 918*795d594fSAndroid Build Coastguard Worker // Set to run expensive tests for correctness too. 919*795d594fSAndroid Build Coastguard Worker boolean HEAVY = false; 920*795d594fSAndroid Build Coastguard Worker 921*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 922*795d594fSAndroid Build Coastguard Worker 923*795d594fSAndroid Build Coastguard Worker int[] a200 = new int[200]; 924*795d594fSAndroid Build Coastguard Worker 925*795d594fSAndroid Build Coastguard Worker // Sorting. 926*795d594fSAndroid Build Coastguard Worker int[] sort = { 5, 4, 1, 9, 10, 2, 7, 6, 3, 8 }; 927*795d594fSAndroid Build Coastguard Worker bubble(sort); 928*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 929*795d594fSAndroid Build Coastguard Worker expectEquals(sort[i], x[i]); 930*795d594fSAndroid Build Coastguard Worker } 931*795d594fSAndroid Build Coastguard Worker 932*795d594fSAndroid Build Coastguard Worker // Periodic adds (1, 3), one at the time. 933*795d594fSAndroid Build Coastguard Worker expectEquals(0, periodicIdiom(-1)); 934*795d594fSAndroid Build Coastguard Worker for (int tc = 0; tc < 32; tc++) { 935*795d594fSAndroid Build Coastguard Worker int expected = (tc >> 1) << 2; 936*795d594fSAndroid Build Coastguard Worker if ((tc & 1) != 0) { 937*795d594fSAndroid Build Coastguard Worker expected += 1; 938*795d594fSAndroid Build Coastguard Worker } 939*795d594fSAndroid Build Coastguard Worker expectEquals(expected, periodicIdiom(tc)); 940*795d594fSAndroid Build Coastguard Worker } 941*795d594fSAndroid Build Coastguard Worker 942*795d594fSAndroid Build Coastguard Worker // Periodic adds (1, 3), one at the time. 943*795d594fSAndroid Build Coastguard Worker expectEquals(0, periodicSequence2(-1)); 944*795d594fSAndroid Build Coastguard Worker for (int tc = 0; tc < 32; tc++) { 945*795d594fSAndroid Build Coastguard Worker int expected = (tc >> 1) << 2; 946*795d594fSAndroid Build Coastguard Worker if ((tc & 1) != 0) { 947*795d594fSAndroid Build Coastguard Worker expected += 1; 948*795d594fSAndroid Build Coastguard Worker } 949*795d594fSAndroid Build Coastguard Worker expectEquals(expected, periodicSequence2(tc)); 950*795d594fSAndroid Build Coastguard Worker } 951*795d594fSAndroid Build Coastguard Worker 952*795d594fSAndroid Build Coastguard Worker // Periodic adds (1, 3, 5, 7), all at once. 953*795d594fSAndroid Build Coastguard Worker expectEquals(0, periodicSequence4(-1)); 954*795d594fSAndroid Build Coastguard Worker for (int tc = 0; tc < 32; tc++) { 955*795d594fSAndroid Build Coastguard Worker expectEquals(tc * 16, periodicSequence4(tc)); 956*795d594fSAndroid Build Coastguard Worker } 957*795d594fSAndroid Build Coastguard Worker 958*795d594fSAndroid Build Coastguard Worker // Periodic adds (1, 3), one at the time. 959*795d594fSAndroid Build Coastguard Worker expectEquals(0, periodicXorSequence(-1)); 960*795d594fSAndroid Build Coastguard Worker for (int tc = 0; tc < 32; tc++) { 961*795d594fSAndroid Build Coastguard Worker int expected = (tc >> 1) << 2; 962*795d594fSAndroid Build Coastguard Worker if ((tc & 1) != 0) { 963*795d594fSAndroid Build Coastguard Worker expected += 1; 964*795d594fSAndroid Build Coastguard Worker } 965*795d594fSAndroid Build Coastguard Worker expectEquals(expected, periodicXorSequence(tc)); 966*795d594fSAndroid Build Coastguard Worker } 967*795d594fSAndroid Build Coastguard Worker 968*795d594fSAndroid Build Coastguard Worker // Large bounds. 969*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightUp1()); 970*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightUp2()); 971*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightUp3()); 972*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightDown1()); 973*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightDown2()); 974*795d594fSAndroid Build Coastguard Worker expectEquals(55, justRightDown3()); 975*795d594fSAndroid Build Coastguard Worker 976*795d594fSAndroid Build Coastguard Worker // Large bounds OOB. 977*795d594fSAndroid Build Coastguard Worker sResult = 0; 978*795d594fSAndroid Build Coastguard Worker try { 979*795d594fSAndroid Build Coastguard Worker justOOBUp(); 980*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 981*795d594fSAndroid Build Coastguard Worker sResult = 1; 982*795d594fSAndroid Build Coastguard Worker } 983*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 984*795d594fSAndroid Build Coastguard Worker sResult = 0; 985*795d594fSAndroid Build Coastguard Worker try { 986*795d594fSAndroid Build Coastguard Worker justOOBDown(); 987*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 988*795d594fSAndroid Build Coastguard Worker sResult = 1; 989*795d594fSAndroid Build Coastguard Worker } 990*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 991*795d594fSAndroid Build Coastguard Worker 992*795d594fSAndroid Build Coastguard Worker // Lower bound goes OOB. 993*795d594fSAndroid Build Coastguard Worker sResult = 0; 994*795d594fSAndroid Build Coastguard Worker try { 995*795d594fSAndroid Build Coastguard Worker lowerOOB(x); 996*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 997*795d594fSAndroid Build Coastguard Worker sResult += 1000; 998*795d594fSAndroid Build Coastguard Worker } 999*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1000*795d594fSAndroid Build Coastguard Worker 1001*795d594fSAndroid Build Coastguard Worker // Upper bound goes OOB. 1002*795d594fSAndroid Build Coastguard Worker sResult = 0; 1003*795d594fSAndroid Build Coastguard Worker try { 1004*795d594fSAndroid Build Coastguard Worker upperOOB(x); 1005*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1006*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1007*795d594fSAndroid Build Coastguard Worker } 1008*795d594fSAndroid Build Coastguard Worker expectEquals(1055, sResult); 1009*795d594fSAndroid Build Coastguard Worker 1010*795d594fSAndroid Build Coastguard Worker // Do while up goes OOB. 1011*795d594fSAndroid Build Coastguard Worker sResult = 0; 1012*795d594fSAndroid Build Coastguard Worker try { 1013*795d594fSAndroid Build Coastguard Worker doWhileUpOOB(); 1014*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1015*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1016*795d594fSAndroid Build Coastguard Worker } 1017*795d594fSAndroid Build Coastguard Worker expectEquals(1055, sResult); 1018*795d594fSAndroid Build Coastguard Worker 1019*795d594fSAndroid Build Coastguard Worker // Do while down goes OOB. 1020*795d594fSAndroid Build Coastguard Worker sResult = 0; 1021*795d594fSAndroid Build Coastguard Worker try { 1022*795d594fSAndroid Build Coastguard Worker doWhileDownOOB(); 1023*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1024*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1025*795d594fSAndroid Build Coastguard Worker } 1026*795d594fSAndroid Build Coastguard Worker expectEquals(1055, sResult); 1027*795d594fSAndroid Build Coastguard Worker 1028*795d594fSAndroid Build Coastguard Worker // Triangular. 1029*795d594fSAndroid Build Coastguard Worker sResult = 0; 1030*795d594fSAndroid Build Coastguard Worker justRightTriangular1(); 1031*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 1032*795d594fSAndroid Build Coastguard Worker if (HEAVY) { 1033*795d594fSAndroid Build Coastguard Worker sResult = 0; 1034*795d594fSAndroid Build Coastguard Worker justRightTriangular2(); 1035*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 1036*795d594fSAndroid Build Coastguard Worker } 1037*795d594fSAndroid Build Coastguard Worker sResult = 0; 1038*795d594fSAndroid Build Coastguard Worker try { 1039*795d594fSAndroid Build Coastguard Worker justOOBTriangular(); 1040*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1041*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1042*795d594fSAndroid Build Coastguard Worker } 1043*795d594fSAndroid Build Coastguard Worker expectEquals(1001, sResult); 1044*795d594fSAndroid Build Coastguard Worker 1045*795d594fSAndroid Build Coastguard Worker // Hidden OOB. 1046*795d594fSAndroid Build Coastguard Worker sResult = 0; 1047*795d594fSAndroid Build Coastguard Worker try { 1048*795d594fSAndroid Build Coastguard Worker hiddenOOB1(10); // no OOB 1049*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1050*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1051*795d594fSAndroid Build Coastguard Worker } 1052*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 1053*795d594fSAndroid Build Coastguard Worker sResult = 0; 1054*795d594fSAndroid Build Coastguard Worker try { 1055*795d594fSAndroid Build Coastguard Worker hiddenOOB1(-2147483648); // OOB 1056*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1057*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1058*795d594fSAndroid Build Coastguard Worker } 1059*795d594fSAndroid Build Coastguard Worker expectEquals(1001, sResult); 1060*795d594fSAndroid Build Coastguard Worker sResult = 0; 1061*795d594fSAndroid Build Coastguard Worker try { 1062*795d594fSAndroid Build Coastguard Worker hiddenOOB2(1); // no OOB 1063*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1064*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1065*795d594fSAndroid Build Coastguard Worker } 1066*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 1067*795d594fSAndroid Build Coastguard Worker sResult = 0; 1068*795d594fSAndroid Build Coastguard Worker try { 1069*795d594fSAndroid Build Coastguard Worker hiddenOOB3(-1); // no OOB 1070*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1071*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1072*795d594fSAndroid Build Coastguard Worker } 1073*795d594fSAndroid Build Coastguard Worker expectEquals(11, sResult); 1074*795d594fSAndroid Build Coastguard Worker 1075*795d594fSAndroid Build Coastguard Worker // Expensive hidden OOB test. 1076*795d594fSAndroid Build Coastguard Worker if (HEAVY) { 1077*795d594fSAndroid Build Coastguard Worker sResult = 0; 1078*795d594fSAndroid Build Coastguard Worker try { 1079*795d594fSAndroid Build Coastguard Worker hiddenOOB2(2147483647); // OOB 1080*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1081*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1082*795d594fSAndroid Build Coastguard Worker } 1083*795d594fSAndroid Build Coastguard Worker expectEquals(1002, sResult); 1084*795d594fSAndroid Build Coastguard Worker sResult = 0; 1085*795d594fSAndroid Build Coastguard Worker try { 1086*795d594fSAndroid Build Coastguard Worker hiddenOOB3(2147483647); // OOB 1087*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1088*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1089*795d594fSAndroid Build Coastguard Worker } 1090*795d594fSAndroid Build Coastguard Worker expectEquals(1011, sResult); 1091*795d594fSAndroid Build Coastguard Worker } 1092*795d594fSAndroid Build Coastguard Worker 1093*795d594fSAndroid Build Coastguard Worker // More hidden OOB. 1094*795d594fSAndroid Build Coastguard Worker sResult = 0; 1095*795d594fSAndroid Build Coastguard Worker try { 1096*795d594fSAndroid Build Coastguard Worker hiddenInfiniteOOB(); 1097*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1098*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1099*795d594fSAndroid Build Coastguard Worker } 1100*795d594fSAndroid Build Coastguard Worker expectEquals(1011, sResult); 1101*795d594fSAndroid Build Coastguard Worker sResult = 0; 1102*795d594fSAndroid Build Coastguard Worker try { 1103*795d594fSAndroid Build Coastguard Worker hiddenFiniteOOB(); 1104*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1105*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1106*795d594fSAndroid Build Coastguard Worker } 1107*795d594fSAndroid Build Coastguard Worker expectEquals(1111, sResult); 1108*795d594fSAndroid Build Coastguard Worker sResult = 0; 1109*795d594fSAndroid Build Coastguard Worker try { 1110*795d594fSAndroid Build Coastguard Worker inductionOOB(a200); 1111*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1112*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1113*795d594fSAndroid Build Coastguard Worker } 1114*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1115*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 200; i++) { 1116*795d594fSAndroid Build Coastguard Worker expectEquals(i < 128 ? i : 0, a200[i]); 1117*795d594fSAndroid Build Coastguard Worker } 1118*795d594fSAndroid Build Coastguard Worker sResult = 0; 1119*795d594fSAndroid Build Coastguard Worker try { 1120*795d594fSAndroid Build Coastguard Worker controlOOB(a200); 1121*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1122*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1123*795d594fSAndroid Build Coastguard Worker } 1124*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1125*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 200; i++) { 1126*795d594fSAndroid Build Coastguard Worker expectEquals(i < 128 ? -i : 0, a200[i]); 1127*795d594fSAndroid Build Coastguard Worker } 1128*795d594fSAndroid Build Coastguard Worker sResult = 0; 1129*795d594fSAndroid Build Coastguard Worker try { 1130*795d594fSAndroid Build Coastguard Worker conversionOOB(a200); 1131*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1132*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1133*795d594fSAndroid Build Coastguard Worker } 1134*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1135*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 200; i++) { 1136*795d594fSAndroid Build Coastguard Worker expectEquals(i < 128 ? i : 0, a200[i]); 1137*795d594fSAndroid Build Coastguard Worker } 1138*795d594fSAndroid Build Coastguard Worker 1139*795d594fSAndroid Build Coastguard Worker // No hoisting after BCE. 1140*795d594fSAndroid Build Coastguard Worker expectEquals(110, doNotHoist(x)); 1141*795d594fSAndroid Build Coastguard Worker 1142*795d594fSAndroid Build Coastguard Worker // Addition. 1143*795d594fSAndroid Build Coastguard Worker { 1144*795d594fSAndroid Build Coastguard Worker int[] e1 ={ 1, 2, 3, 4, 4, 4, 4, 3, 2, 1 }; 1145*795d594fSAndroid Build Coastguard Worker int[] a1 = add(); 1146*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1147*795d594fSAndroid Build Coastguard Worker expectEquals(a1[i], e1[i]); 1148*795d594fSAndroid Build Coastguard Worker } 1149*795d594fSAndroid Build Coastguard Worker } 1150*795d594fSAndroid Build Coastguard Worker 1151*795d594fSAndroid Build Coastguard Worker // Multiplication. 1152*795d594fSAndroid Build Coastguard Worker { 1153*795d594fSAndroid Build Coastguard Worker int[] e1 = { 7, 1, 2, 2, 1, 0, 2, 0, 0, 1 }; 1154*795d594fSAndroid Build Coastguard Worker int[] a1 = multiply1(); 1155*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1156*795d594fSAndroid Build Coastguard Worker expectEquals(a1[i], e1[i]); 1157*795d594fSAndroid Build Coastguard Worker } 1158*795d594fSAndroid Build Coastguard Worker int[] e2 = { 1001, 0, 0, 1, 0, 0, 1, 0, 0, 1 }; 1159*795d594fSAndroid Build Coastguard Worker int[] a2 = multiply2(); 1160*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1161*795d594fSAndroid Build Coastguard Worker expectEquals(a2[i], e2[i]); 1162*795d594fSAndroid Build Coastguard Worker } 1163*795d594fSAndroid Build Coastguard Worker } 1164*795d594fSAndroid Build Coastguard Worker 1165*795d594fSAndroid Build Coastguard Worker // Dynamic BCE. 1166*795d594fSAndroid Build Coastguard Worker sResult = 0; 1167*795d594fSAndroid Build Coastguard Worker try { 1168*795d594fSAndroid Build Coastguard Worker linearDynamicBCE1(x, -1, x.length); 1169*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1170*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1171*795d594fSAndroid Build Coastguard Worker } 1172*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1173*795d594fSAndroid Build Coastguard Worker sResult = 0; 1174*795d594fSAndroid Build Coastguard Worker linearDynamicBCE1(x, 0, x.length); 1175*795d594fSAndroid Build Coastguard Worker expectEquals(55, sResult); 1176*795d594fSAndroid Build Coastguard Worker sResult = 0; 1177*795d594fSAndroid Build Coastguard Worker try { 1178*795d594fSAndroid Build Coastguard Worker linearDynamicBCE1(x, 0, x.length + 1); 1179*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1180*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1181*795d594fSAndroid Build Coastguard Worker } 1182*795d594fSAndroid Build Coastguard Worker expectEquals(1055, sResult); 1183*795d594fSAndroid Build Coastguard Worker 1184*795d594fSAndroid Build Coastguard Worker // Dynamic BCE with offset. 1185*795d594fSAndroid Build Coastguard Worker sResult = 0; 1186*795d594fSAndroid Build Coastguard Worker try { 1187*795d594fSAndroid Build Coastguard Worker linearDynamicBCE2(x, 0, x.length, -1); 1188*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1189*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1190*795d594fSAndroid Build Coastguard Worker } 1191*795d594fSAndroid Build Coastguard Worker expectEquals(1000, sResult); 1192*795d594fSAndroid Build Coastguard Worker sResult = 0; 1193*795d594fSAndroid Build Coastguard Worker linearDynamicBCE2(x, 0, x.length, 0); 1194*795d594fSAndroid Build Coastguard Worker expectEquals(55, sResult); 1195*795d594fSAndroid Build Coastguard Worker sResult = 0; 1196*795d594fSAndroid Build Coastguard Worker try { 1197*795d594fSAndroid Build Coastguard Worker linearDynamicBCE2(x, 0, x.length, 1); 1198*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1199*795d594fSAndroid Build Coastguard Worker sResult += 1000; 1200*795d594fSAndroid Build Coastguard Worker } 1201*795d594fSAndroid Build Coastguard Worker expectEquals(1054, sResult); 1202*795d594fSAndroid Build Coastguard Worker 1203*795d594fSAndroid Build Coastguard Worker // Dynamic BCE candidates. 1204*795d594fSAndroid Build Coastguard Worker expectEquals(55, wrapAroundDynamicBCE(x)); 1205*795d594fSAndroid Build Coastguard Worker expectEquals(15, periodicDynamicBCE(x)); 1206*795d594fSAndroid Build Coastguard Worker expectEquals(55, dynamicBCEPossiblyInfiniteLoop(x, 0, 9)); 1207*795d594fSAndroid Build Coastguard Worker expectEquals(55, noDynamicBCEPossiblyInfiniteLoop(x, 0, 9)); 1208*795d594fSAndroid Build Coastguard Worker expectEquals(55, noDynamicBCEMixedInductionTypes(x, 0, 10)); 1209*795d594fSAndroid Build Coastguard Worker expectEquals(125, dynamicBCEConstantRange(x)); 1210*795d594fSAndroid Build Coastguard Worker 1211*795d594fSAndroid Build Coastguard Worker // Dynamic BCE combined with constant indices. 1212*795d594fSAndroid Build Coastguard Worker int[][] a; 1213*795d594fSAndroid Build Coastguard Worker a = new int[0][0]; 1214*795d594fSAndroid Build Coastguard Worker expectEquals(-1, dynamicBCEAndConstantIndices(x, a, 0, 10)); 1215*795d594fSAndroid Build Coastguard Worker a = new int[100][10]; 1216*795d594fSAndroid Build Coastguard Worker expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10)); 1217*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1218*795d594fSAndroid Build Coastguard Worker expectEquals((i % 10) != 0 ? 1 : 0, a[1][i]); 1219*795d594fSAndroid Build Coastguard Worker expectEquals((i % 10) != 0 ? 2 : 0, a[2][i]); 1220*795d594fSAndroid Build Coastguard Worker expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]); 1221*795d594fSAndroid Build Coastguard Worker } 1222*795d594fSAndroid Build Coastguard Worker a = new int[3][10]; 1223*795d594fSAndroid Build Coastguard Worker sResult = 0; 1224*795d594fSAndroid Build Coastguard Worker try { 1225*795d594fSAndroid Build Coastguard Worker expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10)); 1226*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1227*795d594fSAndroid Build Coastguard Worker sResult = 1; 1228*795d594fSAndroid Build Coastguard Worker } 1229*795d594fSAndroid Build Coastguard Worker expectEquals(1, sResult); 1230*795d594fSAndroid Build Coastguard Worker expectEquals(a[1][1], 1); 1231*795d594fSAndroid Build Coastguard Worker expectEquals(a[2][1], 2); 1232*795d594fSAndroid Build Coastguard Worker 1233*795d594fSAndroid Build Coastguard Worker // Dynamic BCE combined with constant indices of all types. 1234*795d594fSAndroid Build Coastguard Worker boolean[] x1 = { true }; 1235*795d594fSAndroid Build Coastguard Worker byte[] x2 = { 2 }; 1236*795d594fSAndroid Build Coastguard Worker char[] x3 = { 3 }; 1237*795d594fSAndroid Build Coastguard Worker short[] x4 = { 4 }; 1238*795d594fSAndroid Build Coastguard Worker int[] x5 = { 5 }; 1239*795d594fSAndroid Build Coastguard Worker long[] x6 = { 6 }; 1240*795d594fSAndroid Build Coastguard Worker float[] x7 = { 7 }; 1241*795d594fSAndroid Build Coastguard Worker double[] x8 = { 8 }; 1242*795d594fSAndroid Build Coastguard Worker expectEquals(415, 1243*795d594fSAndroid Build Coastguard Worker dynamicBCEAndConstantIndicesAllPrimTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, 0, 10)); 1244*795d594fSAndroid Build Coastguard Worker Integer[] x9 = { 9 }; 1245*795d594fSAndroid Build Coastguard Worker expectEquals(145, dynamicBCEAndConstantIndexRefType(x, x9, 0, 10)); 1246*795d594fSAndroid Build Coastguard Worker 1247*795d594fSAndroid Build Coastguard Worker expectEquals(99, shortIndex(x)); 1248*795d594fSAndroid Build Coastguard Worker 1249*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 1250*795d594fSAndroid Build Coastguard Worker } 1251*795d594fSAndroid Build Coastguard Worker 1252*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 1253*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1254*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1255*795d594fSAndroid Build Coastguard Worker } 1256*795d594fSAndroid Build Coastguard Worker } 1257*795d594fSAndroid Build Coastguard Worker } 1258