1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 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 dynamic BCE. In all cases, 19*795d594fSAndroid Build Coastguard Worker // bounds check on a[] is resolved statically. Bounds checks on b[] 20*795d594fSAndroid Build Coastguard Worker // exercise various different scenarios. In all cases, loop-based 21*795d594fSAndroid Build Coastguard Worker // dynamic BCE is better than the dominator-based BCE, since it 22*795d594fSAndroid Build Coastguard Worker // generates the test outside the loop. 23*795d594fSAndroid Build Coastguard Worker // 24*795d594fSAndroid Build Coastguard Worker public class Main { 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneConstantIndex(int[], int[]) BCE (before) 27*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 28*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 29*795d594fSAndroid Build Coastguard Worker // 30*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneConstantIndex(int[], int[]) BCE (after) 31*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 32*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 33*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 34*795d594fSAndroid Build Coastguard Worker // 35*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneConstantIndex(int[], int[]) BCE (after) 36*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck oneConstantIndex(int[] a, int[] b)37*795d594fSAndroid Build Coastguard Worker public static void oneConstantIndex(int[] a, int[] b) { 38*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires two deopts: one null and one bound. 39*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 40*795d594fSAndroid Build Coastguard Worker a[i] = b[1]; 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker } 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleConstantIndices(int[], int[]) BCE (before) 45*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 46*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 47*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 48*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 49*795d594fSAndroid Build Coastguard Worker // 50*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleConstantIndices(int[], int[]) BCE (after) 51*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 52*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 53*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 54*795d594fSAndroid Build Coastguard Worker // 55*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleConstantIndices(int[], int[]) BCE (after) 56*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck multipleConstantIndices(int[] a, int[] b)57*795d594fSAndroid Build Coastguard Worker public static void multipleConstantIndices(int[] a, int[] b) { 58*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires two deopts: one null and one bound. 59*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 60*795d594fSAndroid Build Coastguard Worker a[i] = b[0] + b[1] + b[2]; 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneInvariantIndex(int[], int[], int) BCE (before) 65*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 66*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 67*795d594fSAndroid Build Coastguard Worker // 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneInvariantIndex(int[], int[], int) BCE (after) 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 71*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 72*795d594fSAndroid Build Coastguard Worker // 73*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneInvariantIndex(int[], int[], int) BCE (after) 74*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck oneInvariantIndex(int[] a, int[] b, int c)75*795d594fSAndroid Build Coastguard Worker public static void oneInvariantIndex(int[] a, int[] b, int c) { 76*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires two deopts: one null and one bound. 77*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 78*795d594fSAndroid Build Coastguard Worker a[i] = b[c]; 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker } 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleInvariantIndices(int[], int[], int) BCE (before) 83*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 84*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 85*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 86*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 87*795d594fSAndroid Build Coastguard Worker // 88*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleInvariantIndices(int[], int[], int) BCE (after) 89*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 90*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 91*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 92*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 93*795d594fSAndroid Build Coastguard Worker // 94*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleInvariantIndices(int[], int[], int) BCE (after) 95*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck multipleInvariantIndices(int[] a, int[] b, int c)96*795d594fSAndroid Build Coastguard Worker public static void multipleInvariantIndices(int[] a, int[] b, int c) { 97*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires three deopts: one null and two bounds. 98*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 99*795d594fSAndroid Build Coastguard Worker a[i] = b[c-1] + b[c] + b[c+1]; 100*795d594fSAndroid Build Coastguard Worker } 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneUnitStride(int[], int[]) BCE (before) 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 106*795d594fSAndroid Build Coastguard Worker // 107*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneUnitStride(int[], int[]) BCE (after) 108*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 109*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 110*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 111*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 112*795d594fSAndroid Build Coastguard Worker // 113*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneUnitStride(int[], int[]) BCE (after) 114*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck oneUnitStride(int[] a, int[] b)115*795d594fSAndroid Build Coastguard Worker public static void oneUnitStride(int[] a, int[] b) { 116*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires three deopts: one null and two bounds. 117*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 118*795d594fSAndroid Build Coastguard Worker a[i] = b[i]; 119*795d594fSAndroid Build Coastguard Worker } 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStrides(int[], int[]) BCE (before) 123*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 124*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 125*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 126*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 127*795d594fSAndroid Build Coastguard Worker // 128*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStrides(int[], int[]) BCE (after) 129*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 130*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 131*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 132*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 133*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 134*795d594fSAndroid Build Coastguard Worker // 135*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStrides(int[], int[]) instruction_simplifier$before_codegen (after) 136*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 138*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 139*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 140*795d594fSAndroid Build Coastguard Worker // 141*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStrides(int[], int[]) BCE (after) 142*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck multipleUnitStrides(int[] a, int[] b)143*795d594fSAndroid Build Coastguard Worker public static void multipleUnitStrides(int[] a, int[] b) { 144*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires four deopts: one null and three bounds. 145*795d594fSAndroid Build Coastguard Worker // One redundant deopt is removed by simplifier. 146*795d594fSAndroid Build Coastguard Worker // TODO: range information could remove another 147*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < a.length - 1; i++) { 148*795d594fSAndroid Build Coastguard Worker a[i] = b[i-1] + b[i] + b[i+1]; 149*795d594fSAndroid Build Coastguard Worker } 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStridesConditional(int[], int[]) BCE (before) 153*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 154*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 155*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 156*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 157*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 158*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 159*795d594fSAndroid Build Coastguard Worker // 160*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStridesConditional(int[], int[]) BCE (after) 161*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 162*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 163*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 164*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 165*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 166*795d594fSAndroid Build Coastguard Worker // 167*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStridesConditional(int[], int[]) instruction_simplifier$before_codegen (after) 168*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 169*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 170*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 171*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 172*795d594fSAndroid Build Coastguard Worker // 173*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.multipleUnitStridesConditional(int[], int[]) BCE (after) 174*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck multipleUnitStridesConditional(int[] a, int[] b)175*795d594fSAndroid Build Coastguard Worker public static void multipleUnitStridesConditional(int[] a, int[] b) { 176*795d594fSAndroid Build Coastguard Worker // Dynamic bce on b requires four deopts: one null and three bounds. 177*795d594fSAndroid Build Coastguard Worker // The two conditional references may be included, since they are in range. 178*795d594fSAndroid Build Coastguard Worker // One redundant deopt is removed by simplifier. 179*795d594fSAndroid Build Coastguard Worker for (int i = 2; i < a.length - 2; i++) { 180*795d594fSAndroid Build Coastguard Worker int t = b[i-2] + b[i] + b[i+2] + (((i & 1) == 0) ? b[i+1] : b[i-1]); 181*795d594fSAndroid Build Coastguard Worker a[i] = t; 182*795d594fSAndroid Build Coastguard Worker } 183*795d594fSAndroid Build Coastguard Worker } 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shifter(int[]) BCE (before) 186*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 187*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 188*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 189*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 190*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 191*795d594fSAndroid Build Coastguard Worker // 192*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shifter(int[]) BCE (after) 193*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 194*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 195*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 196*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 197*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 198*795d594fSAndroid Build Coastguard Worker // 199*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shifter(int[]) instruction_simplifier$before_codegen (after) 200*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 201*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 202*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 203*795d594fSAndroid Build Coastguard Worker // 204*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shifter(int[]) BCE (after) 205*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck shifter(int[] x)206*795d594fSAndroid Build Coastguard Worker public static void shifter(int[] x) { 207*795d594fSAndroid Build Coastguard Worker // Real-life example: should have four deopts: one null and three bounds. 208*795d594fSAndroid Build Coastguard Worker // Two redundant deopts are removed by simplifier. 209*795d594fSAndroid Build Coastguard Worker for (int i = 16; i < 80; i++) { 210*795d594fSAndroid Build Coastguard Worker int t = x[i - 3] ^ x[i - 8] ^ x[i - 14] ^ x[i - 16]; 211*795d594fSAndroid Build Coastguard Worker x[i] = t << 1 | t >>> 31; 212*795d594fSAndroid Build Coastguard Worker } 213*795d594fSAndroid Build Coastguard Worker } 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.stencil(int[], int, int) BCE (before) 216*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> 217*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 218*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 219*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 220*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:<<Loop>> 221*795d594fSAndroid Build Coastguard Worker // 222*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.stencil(int[], int, int) BCE (after) 223*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 224*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 225*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 226*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 227*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 228*795d594fSAndroid Build Coastguard Worker // 229*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.stencil(int[], int, int) BCE (after) 230*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck stencil(int[] array, int start, int end)231*795d594fSAndroid Build Coastguard Worker public static void stencil(int[] array, int start, int end) { 232*795d594fSAndroid Build Coastguard Worker // Real-life example: should have four deopts: one null and three bounds. 233*795d594fSAndroid Build Coastguard Worker for (int i = end; i >= start; i--) { 234*795d594fSAndroid Build Coastguard Worker array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5; 235*795d594fSAndroid Build Coastguard Worker } 236*795d594fSAndroid Build Coastguard Worker } 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound1(int[], short) BCE (before) 239*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 240*795d594fSAndroid Build Coastguard Worker // 241*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound1(int[], short) BCE (after) 242*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 243*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 244*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 245*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 246*795d594fSAndroid Build Coastguard Worker // 247*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound1(int[], short) BCE (after) 248*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck shortBound1(int[] array, short s)249*795d594fSAndroid Build Coastguard Worker public static void shortBound1(int[] array, short s) { 250*795d594fSAndroid Build Coastguard Worker // Lower precision bound will appear in deopt arithmetic 251*795d594fSAndroid Build Coastguard Worker // and follows normal implicit widening conversion. 252*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < s; i++) { 253*795d594fSAndroid Build Coastguard Worker array[i] = 222; 254*795d594fSAndroid Build Coastguard Worker } 255*795d594fSAndroid Build Coastguard Worker } 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound2(int[], short) BCE (before) 258*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 259*795d594fSAndroid Build Coastguard Worker // 260*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound2(int[], short) BCE (after) 261*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 262*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 263*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Deoptimize loop:none 264*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize 265*795d594fSAndroid Build Coastguard Worker // 266*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.shortBound2(int[], short) BCE (after) 267*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck shortBound2(int[] array, short s)268*795d594fSAndroid Build Coastguard Worker public static void shortBound2(int[] array, short s) { 269*795d594fSAndroid Build Coastguard Worker // Lower precision bound will appear in deopt arithmetic 270*795d594fSAndroid Build Coastguard Worker // and follows normal implicit widening conversion. 271*795d594fSAndroid Build Coastguard Worker for (int i = 0; s > i; i++) { 272*795d594fSAndroid Build Coastguard Worker array[i] = 444; 273*795d594fSAndroid Build Coastguard Worker } 274*795d594fSAndroid Build Coastguard Worker } 275*795d594fSAndroid Build Coastguard Worker 276*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.narrowingFromLong(int[], int) BCE (before) 277*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 278*795d594fSAndroid Build Coastguard Worker // 279*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.narrowingFromLong(int[], int) BCE (after) 280*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} narrowingFromLong(int[] array, int n)281*795d594fSAndroid Build Coastguard Worker public static void narrowingFromLong(int[] array, int n) { 282*795d594fSAndroid Build Coastguard Worker // Parallel induction in long precision that is narrowed provides type 283*795d594fSAndroid Build Coastguard Worker // conversion challenges for BCE in deopt arithmetic when combined 284*795d594fSAndroid Build Coastguard Worker // with the int loop induction. Therefore, currently skipped. 285*795d594fSAndroid Build Coastguard Worker long l = 0; 286*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++, l++) { 287*795d594fSAndroid Build Coastguard Worker array[(int)l] = 888; 288*795d594fSAndroid Build Coastguard Worker } 289*795d594fSAndroid Build Coastguard Worker } 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker // 292*795d594fSAndroid Build Coastguard Worker // Verifier. 293*795d594fSAndroid Build Coastguard Worker // 294*795d594fSAndroid Build Coastguard Worker main(String[] args)295*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 296*795d594fSAndroid Build Coastguard Worker int[] a = new int[10]; 297*795d594fSAndroid Build Coastguard Worker int b[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 298*795d594fSAndroid Build Coastguard Worker int b1[] = { 100 }; 299*795d594fSAndroid Build Coastguard Worker 300*795d594fSAndroid Build Coastguard Worker oneConstantIndex(a, b); 301*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 302*795d594fSAndroid Build Coastguard Worker expectEquals(2, a[i]); 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker try { 305*795d594fSAndroid Build Coastguard Worker oneConstantIndex(a, b1); 306*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 307*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 308*795d594fSAndroid Build Coastguard Worker } 309*795d594fSAndroid Build Coastguard Worker 310*795d594fSAndroid Build Coastguard Worker multipleConstantIndices(a, b); 311*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 312*795d594fSAndroid Build Coastguard Worker expectEquals(6, a[i]); 313*795d594fSAndroid Build Coastguard Worker } 314*795d594fSAndroid Build Coastguard Worker try { 315*795d594fSAndroid Build Coastguard Worker multipleConstantIndices(a, b1); 316*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 317*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 318*795d594fSAndroid Build Coastguard Worker } 319*795d594fSAndroid Build Coastguard Worker 320*795d594fSAndroid Build Coastguard Worker oneInvariantIndex(a, b, 1); 321*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 322*795d594fSAndroid Build Coastguard Worker expectEquals(2, a[i]); 323*795d594fSAndroid Build Coastguard Worker } 324*795d594fSAndroid Build Coastguard Worker try { 325*795d594fSAndroid Build Coastguard Worker oneInvariantIndex(a, b1, 1); 326*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 327*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 328*795d594fSAndroid Build Coastguard Worker } 329*795d594fSAndroid Build Coastguard Worker 330*795d594fSAndroid Build Coastguard Worker multipleInvariantIndices(a, b, 1); 331*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 332*795d594fSAndroid Build Coastguard Worker expectEquals(6, a[i]); 333*795d594fSAndroid Build Coastguard Worker } 334*795d594fSAndroid Build Coastguard Worker try { 335*795d594fSAndroid Build Coastguard Worker multipleInvariantIndices(a, b1, 1); 336*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 337*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 338*795d594fSAndroid Build Coastguard Worker } 339*795d594fSAndroid Build Coastguard Worker 340*795d594fSAndroid Build Coastguard Worker oneUnitStride(a, b); 341*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 342*795d594fSAndroid Build Coastguard Worker expectEquals(i + 1, a[i]); 343*795d594fSAndroid Build Coastguard Worker } 344*795d594fSAndroid Build Coastguard Worker try { 345*795d594fSAndroid Build Coastguard Worker oneUnitStride(a, b1); 346*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 347*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 348*795d594fSAndroid Build Coastguard Worker expectEquals(100, a[0]); 349*795d594fSAndroid Build Coastguard Worker } 350*795d594fSAndroid Build Coastguard Worker 351*795d594fSAndroid Build Coastguard Worker multipleUnitStrides(a, b); 352*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < a.length - 1; i++) { 353*795d594fSAndroid Build Coastguard Worker expectEquals(3 * i + 3, a[i]); 354*795d594fSAndroid Build Coastguard Worker } 355*795d594fSAndroid Build Coastguard Worker try { 356*795d594fSAndroid Build Coastguard Worker multipleUnitStrides(a, b1); 357*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 358*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 359*795d594fSAndroid Build Coastguard Worker } 360*795d594fSAndroid Build Coastguard Worker 361*795d594fSAndroid Build Coastguard Worker multipleUnitStridesConditional(a, b); 362*795d594fSAndroid Build Coastguard Worker for (int i = 2; i < a.length - 2; i++) { 363*795d594fSAndroid Build Coastguard Worker int e = 3 * i + 3 + (((i & 1) == 0) ? i + 2 : i); 364*795d594fSAndroid Build Coastguard Worker expectEquals(e, a[i]); 365*795d594fSAndroid Build Coastguard Worker } 366*795d594fSAndroid Build Coastguard Worker try { 367*795d594fSAndroid Build Coastguard Worker multipleUnitStridesConditional(a, b1); 368*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 369*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 370*795d594fSAndroid Build Coastguard Worker } 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker shortBound1(a, (short)a.length); 373*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 374*795d594fSAndroid Build Coastguard Worker expectEquals(222, a[i]); 375*795d594fSAndroid Build Coastguard Worker } 376*795d594fSAndroid Build Coastguard Worker shortBound2(a, (short)a.length); 377*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 378*795d594fSAndroid Build Coastguard Worker expectEquals(444, a[i]); 379*795d594fSAndroid Build Coastguard Worker } 380*795d594fSAndroid Build Coastguard Worker 381*795d594fSAndroid Build Coastguard Worker try { 382*795d594fSAndroid Build Coastguard Worker shortBound1(a, (short)(a.length + 1)); 383*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 384*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 385*795d594fSAndroid Build Coastguard Worker } 386*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 387*795d594fSAndroid Build Coastguard Worker expectEquals(222, a[i]); 388*795d594fSAndroid Build Coastguard Worker } 389*795d594fSAndroid Build Coastguard Worker 390*795d594fSAndroid Build Coastguard Worker try { 391*795d594fSAndroid Build Coastguard Worker shortBound2(a, (short)(a.length + 1)); 392*795d594fSAndroid Build Coastguard Worker throw new Error("Should throw AIOOBE"); 393*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 394*795d594fSAndroid Build Coastguard Worker } 395*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 396*795d594fSAndroid Build Coastguard Worker expectEquals(444, a[i]); 397*795d594fSAndroid Build Coastguard Worker } 398*795d594fSAndroid Build Coastguard Worker 399*795d594fSAndroid Build Coastguard Worker narrowingFromLong(a, a.length); 400*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 401*795d594fSAndroid Build Coastguard Worker expectEquals(888, a[i]); 402*795d594fSAndroid Build Coastguard Worker } 403*795d594fSAndroid Build Coastguard Worker 404*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 405*795d594fSAndroid Build Coastguard Worker } 406*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)407*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 408*795d594fSAndroid Build Coastguard Worker if (expected != result) { 409*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 410*795d594fSAndroid Build Coastguard Worker } 411*795d594fSAndroid Build Coastguard Worker } 412*795d594fSAndroid Build Coastguard Worker } 413