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 * Regression tests for loop optimizations. 19*795d594fSAndroid Build Coastguard Worker */ 20*795d594fSAndroid Build Coastguard Worker public class Main { 21*795d594fSAndroid Build Coastguard Worker ensureJitCompiled(Class<?> cls, String methodName)22*795d594fSAndroid Build Coastguard Worker private static native void ensureJitCompiled(Class<?> cls, String methodName); 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitFirst(int) loop_optimization (before) 25*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 26*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 27*795d594fSAndroid Build Coastguard Worker // 28*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitFirst(int) loop_optimization (after) 29*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 30*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none earlyExitFirst(int m)31*795d594fSAndroid Build Coastguard Worker static int earlyExitFirst(int m) { 32*795d594fSAndroid Build Coastguard Worker int k = 0; 33*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 34*795d594fSAndroid Build Coastguard Worker if (i == m) { 35*795d594fSAndroid Build Coastguard Worker return k; 36*795d594fSAndroid Build Coastguard Worker } 37*795d594fSAndroid Build Coastguard Worker k++; 38*795d594fSAndroid Build Coastguard Worker } 39*795d594fSAndroid Build Coastguard Worker return k; 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitLast(int) loop_optimization (before) 43*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 44*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 45*795d594fSAndroid Build Coastguard Worker // 46*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitLast(int) loop_optimization (after) 47*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 48*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none earlyExitLast(int m)49*795d594fSAndroid Build Coastguard Worker static int earlyExitLast(int m) { 50*795d594fSAndroid Build Coastguard Worker int k = 0; 51*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 52*795d594fSAndroid Build Coastguard Worker k++; 53*795d594fSAndroid Build Coastguard Worker if (i == m) { 54*795d594fSAndroid Build Coastguard Worker return k; 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker } 57*795d594fSAndroid Build Coastguard Worker return k; 58*795d594fSAndroid Build Coastguard Worker } 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitNested() loop_optimization (before) 61*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 62*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none 63*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 64*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop2>> outer_loop:<<Loop1>> 65*795d594fSAndroid Build Coastguard Worker // 66*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitNested() loop_optimization (after) 67*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 68*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none 69*795d594fSAndroid Build Coastguard Worker // 70*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.earlyExitNested() loop_optimization (after) 71*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:{{B\d+}} earlyExitNested()72*795d594fSAndroid Build Coastguard Worker static int earlyExitNested() { 73*795d594fSAndroid Build Coastguard Worker int offset = 0; 74*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) { 75*795d594fSAndroid Build Coastguard Worker int start = offset; 76*795d594fSAndroid Build Coastguard Worker // This loop can be removed. 77*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 2; j++) { 78*795d594fSAndroid Build Coastguard Worker offset++; 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker if (i == 1) { 81*795d594fSAndroid Build Coastguard Worker return start; 82*795d594fSAndroid Build Coastguard Worker } 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker return 0; 85*795d594fSAndroid Build Coastguard Worker } 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // Regression test for b/33774618: transfer operations involving 88*795d594fSAndroid Build Coastguard Worker // narrowing linear induction should be done correctly. 89*795d594fSAndroid Build Coastguard Worker // 90*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (before) 91*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 92*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 93*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 94*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 95*795d594fSAndroid Build Coastguard Worker // 96*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (after) 97*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 98*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 99*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 100*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none transferNarrowWrap()101*795d594fSAndroid Build Coastguard Worker static int transferNarrowWrap() { 102*795d594fSAndroid Build Coastguard Worker short x = 0; 103*795d594fSAndroid Build Coastguard Worker int w = 10; 104*795d594fSAndroid Build Coastguard Worker int v = 3; 105*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 106*795d594fSAndroid Build Coastguard Worker v = w + 1; // transfer on wrap-around 107*795d594fSAndroid Build Coastguard Worker w = x; // wrap-around 108*795d594fSAndroid Build Coastguard Worker x += 2; // narrowing linear 109*795d594fSAndroid Build Coastguard Worker } 110*795d594fSAndroid Build Coastguard Worker return v; 111*795d594fSAndroid Build Coastguard Worker } 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker // Regression test for b/33774618: transfer operations involving 114*795d594fSAndroid Build Coastguard Worker // narrowing linear induction should be done correctly 115*795d594fSAndroid Build Coastguard Worker // (currently rejected, could be improved). 116*795d594fSAndroid Build Coastguard Worker // 117*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialShort() loop_optimization (before) 118*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 119*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 120*795d594fSAndroid Build Coastguard Worker // 121*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialShort() loop_optimization (after) 122*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 123*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none polynomialShort()124*795d594fSAndroid Build Coastguard Worker static int polynomialShort() { 125*795d594fSAndroid Build Coastguard Worker int x = 0; 126*795d594fSAndroid Build Coastguard Worker for (short i = 0; i < 10; i++) { 127*795d594fSAndroid Build Coastguard Worker x = x - i; // polynomial on narrowing linear 128*795d594fSAndroid Build Coastguard Worker } 129*795d594fSAndroid Build Coastguard Worker return x; 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker // Regression test for b/33774618: transfer operations involving 133*795d594fSAndroid Build Coastguard Worker // narrowing linear induction should be done correctly 134*795d594fSAndroid Build Coastguard Worker // (currently rejected, could be improved). 135*795d594fSAndroid Build Coastguard Worker // 136*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (before) 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 138*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 139*795d594fSAndroid Build Coastguard Worker // 140*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (after) 141*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 142*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none polynomialIntFromLong()143*795d594fSAndroid Build Coastguard Worker static int polynomialIntFromLong() { 144*795d594fSAndroid Build Coastguard Worker int x = 0; 145*795d594fSAndroid Build Coastguard Worker for (long i = 0; i < 10; i++) { 146*795d594fSAndroid Build Coastguard Worker x = x - (int) i; // polynomial on narrowing linear 147*795d594fSAndroid Build Coastguard Worker } 148*795d594fSAndroid Build Coastguard Worker return x; 149*795d594fSAndroid Build Coastguard Worker } 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialInt() loop_optimization (before) 152*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 153*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 154*795d594fSAndroid Build Coastguard Worker // 155*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialInt() loop_optimization (after) 156*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 157*795d594fSAndroid Build Coastguard Worker // 158*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.polynomialInt() instruction_simplifier$before_codegen (after) 159*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant -45 loop:none 160*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none polynomialInt()161*795d594fSAndroid Build Coastguard Worker static int polynomialInt() { 162*795d594fSAndroid Build Coastguard Worker int x = 0; 163*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 164*795d594fSAndroid Build Coastguard Worker x = x - i; 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker return x; 167*795d594fSAndroid Build Coastguard Worker } 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker // Regression test for b/34779592 (found with fuzz testing): overflow for last value 170*795d594fSAndroid Build Coastguard Worker // of division truncates to zero, for multiplication it simply truncates. 171*795d594fSAndroid Build Coastguard Worker // 172*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntDivLastValue(int) loop_optimization (before) 173*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 174*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 175*795d594fSAndroid Build Coastguard Worker // 176*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntDivLastValue(int) loop_optimization (after) 177*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 178*795d594fSAndroid Build Coastguard Worker // 179*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntDivLastValue(int) instruction_simplifier$before_codegen (after) 180*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none 181*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none geoIntDivLastValue(int x)182*795d594fSAndroid Build Coastguard Worker static int geoIntDivLastValue(int x) { 183*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) { 184*795d594fSAndroid Build Coastguard Worker x /= 1081788608; 185*795d594fSAndroid Build Coastguard Worker } 186*795d594fSAndroid Build Coastguard Worker return x; 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntMulLastValue(int) loop_optimization (before) 190*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 191*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 192*795d594fSAndroid Build Coastguard Worker // 193*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntMulLastValue(int) loop_optimization (after) 194*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 195*795d594fSAndroid Build Coastguard Worker // 196*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoIntMulLastValue(int) instruction_simplifier$before_codegen (after) 197*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 198*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant -194211840 loop:none 199*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none 200*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Mul>>] loop:none geoIntMulLastValue(int x)201*795d594fSAndroid Build Coastguard Worker static int geoIntMulLastValue(int x) { 202*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) { 203*795d594fSAndroid Build Coastguard Worker x *= 1081788608; 204*795d594fSAndroid Build Coastguard Worker } 205*795d594fSAndroid Build Coastguard Worker return x; 206*795d594fSAndroid Build Coastguard Worker } 207*795d594fSAndroid Build Coastguard Worker 208*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue(long) loop_optimization (before) 209*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 210*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 211*795d594fSAndroid Build Coastguard Worker // 212*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue(long) loop_optimization (after) 213*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 214*795d594fSAndroid Build Coastguard Worker // 215*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue(long) instruction_simplifier$before_codegen (after) 216*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Long:j\d+>> LongConstant 0 loop:none 217*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Long>>] loop:none 218*795d594fSAndroid Build Coastguard Worker // 219*795d594fSAndroid Build Coastguard Worker // Tests overflow in the divisor (while updating intermediate result). geoLongDivLastValue(long x)220*795d594fSAndroid Build Coastguard Worker static long geoLongDivLastValue(long x) { 221*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 222*795d594fSAndroid Build Coastguard Worker x /= 1081788608; 223*795d594fSAndroid Build Coastguard Worker } 224*795d594fSAndroid Build Coastguard Worker return x; 225*795d594fSAndroid Build Coastguard Worker } 226*795d594fSAndroid Build Coastguard Worker 227*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue() loop_optimization (before) 228*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 229*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 230*795d594fSAndroid Build Coastguard Worker // 231*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue() loop_optimization (after) 232*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 233*795d594fSAndroid Build Coastguard Worker // 234*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongDivLastValue() instruction_simplifier$before_codegen (after) 235*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Long:j\d+>> LongConstant 0 loop:none 236*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Long>>] loop:none 237*795d594fSAndroid Build Coastguard Worker // 238*795d594fSAndroid Build Coastguard Worker // Tests overflow in the divisor (while updating base). geoLongDivLastValue()239*795d594fSAndroid Build Coastguard Worker static long geoLongDivLastValue() { 240*795d594fSAndroid Build Coastguard Worker long x = -1; 241*795d594fSAndroid Build Coastguard Worker for (int i2 = 0; i2 < 2; i2++) { 242*795d594fSAndroid Build Coastguard Worker x /= (Long.MAX_VALUE); 243*795d594fSAndroid Build Coastguard Worker } 244*795d594fSAndroid Build Coastguard Worker return x; 245*795d594fSAndroid Build Coastguard Worker } 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongMulLastValue(long) loop_optimization (before) 248*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 249*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 250*795d594fSAndroid Build Coastguard Worker // 251*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongMulLastValue(long) loop_optimization (after) 252*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 253*795d594fSAndroid Build Coastguard Worker // 254*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.geoLongMulLastValue(long) instruction_simplifier$before_codegen (after) 255*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:j\d+>> ParameterValue loop:none 256*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Long:j\d+>> LongConstant -8070450532247928832 loop:none 257*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Par>>,<<Long>>] loop:none 258*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Mul>>] loop:none geoLongMulLastValue(long x)259*795d594fSAndroid Build Coastguard Worker static long geoLongMulLastValue(long x) { 260*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 261*795d594fSAndroid Build Coastguard Worker x *= 1081788608; 262*795d594fSAndroid Build Coastguard Worker } 263*795d594fSAndroid Build Coastguard Worker return x; 264*795d594fSAndroid Build Coastguard Worker } 265*795d594fSAndroid Build Coastguard Worker 266*795d594fSAndroid Build Coastguard Worker // If vectorized, the narrowing subscript should not cause 267*795d594fSAndroid Build Coastguard Worker // type inconsistencies in the synthesized code. narrowingSubscript(float[] a)268*795d594fSAndroid Build Coastguard Worker static void narrowingSubscript(float[] a) { 269*795d594fSAndroid Build Coastguard Worker float val = 2.0f; 270*795d594fSAndroid Build Coastguard Worker for (long i = 0; i < a.length; i++) { 271*795d594fSAndroid Build Coastguard Worker a[(int) i] += val; 272*795d594fSAndroid Build Coastguard Worker } 273*795d594fSAndroid Build Coastguard Worker } 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker // If vectorized, invariant stride should be recognized 276*795d594fSAndroid Build Coastguard Worker // as a reduction, not a unit stride in outer loop. reduc(int[] xx, int[] yy)277*795d594fSAndroid Build Coastguard Worker static void reduc(int[] xx, int[] yy) { 278*795d594fSAndroid Build Coastguard Worker for (int i0 = 0; i0 < 2; i0++) { 279*795d594fSAndroid Build Coastguard Worker for (int i1 = 0; i1 < 469; i1++) { 280*795d594fSAndroid Build Coastguard Worker xx[i0] -= (++yy[i1]); 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker } 283*795d594fSAndroid Build Coastguard Worker } 284*795d594fSAndroid Build Coastguard Worker 285*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.string2Bytes(char[], java.lang.String) loop_optimization (before) 286*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none 287*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 288*795d594fSAndroid Build Coastguard Worker // 289*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: void Main.string2Bytes(char[], java.lang.String) loop_optimization (after) 290*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecLoad 291*795d594fSAndroid Build Coastguard Worker // 292*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: void Main.string2Bytes(char[], java.lang.String) loop_optimization (after) 293*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 294*795d594fSAndroid Build Coastguard Worker // 295*795d594fSAndroid Build Coastguard Worker // TODO: Support CharAt for SVE. 296*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecLoad 297*795d594fSAndroid Build Coastguard Worker // 298*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 299*795d594fSAndroid Build Coastguard Worker // 300*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 301*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none 302*795d594fSAndroid Build Coastguard Worker // 303*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: 304*795d594fSAndroid Build Coastguard Worker // 305*795d594fSAndroid Build Coastguard Worker // NOTE: should correctly deal with compressed and uncompressed cases. string2Bytes(char[] a, String b)306*795d594fSAndroid Build Coastguard Worker private static void string2Bytes(char[] a, String b) { 307*795d594fSAndroid Build Coastguard Worker int min = Math.min(a.length, b.length()); 308*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < min; i++) { 309*795d594fSAndroid Build Coastguard Worker a[i] = b.charAt(i); 310*795d594fSAndroid Build Coastguard Worker } 311*795d594fSAndroid Build Coastguard Worker } 312*795d594fSAndroid Build Coastguard Worker 313*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after) 314*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecLoad 315*795d594fSAndroid Build Coastguard Worker 316*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after) 317*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 318*795d594fSAndroid Build Coastguard Worker // 319*795d594fSAndroid Build Coastguard Worker // TODO: Support CharAt for SVE. 320*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecLoad 321*795d594fSAndroid Build Coastguard Worker // 322*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 323*795d594fSAndroid Build Coastguard Worker // 324*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 325*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none 326*795d594fSAndroid Build Coastguard Worker // 327*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: $noinline$stringToShorts(short[] dest, String src)328*795d594fSAndroid Build Coastguard Worker private static void $noinline$stringToShorts(short[] dest, String src) { 329*795d594fSAndroid Build Coastguard Worker int min = Math.min(dest.length, src.length()); 330*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < min; ++i) { 331*795d594fSAndroid Build Coastguard Worker dest[i] = (short) src.charAt(i); 332*795d594fSAndroid Build Coastguard Worker } 333*795d594fSAndroid Build Coastguard Worker } 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker // A strange function that does not inline. $noinline$foo(boolean x, int n)336*795d594fSAndroid Build Coastguard Worker private static void $noinline$foo(boolean x, int n) { 337*795d594fSAndroid Build Coastguard Worker if (n < 0) 338*795d594fSAndroid Build Coastguard Worker throw new Error("oh no"); 339*795d594fSAndroid Build Coastguard Worker if (n > 100) { 340*795d594fSAndroid Build Coastguard Worker $noinline$foo(!x, n - 1); 341*795d594fSAndroid Build Coastguard Worker $noinline$foo(!x, n - 2); 342*795d594fSAndroid Build Coastguard Worker $noinline$foo(!x, n - 3); 343*795d594fSAndroid Build Coastguard Worker $noinline$foo(!x, n - 4); 344*795d594fSAndroid Build Coastguard Worker } 345*795d594fSAndroid Build Coastguard Worker } 346*795d594fSAndroid Build Coastguard Worker 347*795d594fSAndroid Build Coastguard Worker // A loop with environment uses of x (the terminating condition). As exposed by bug 348*795d594fSAndroid Build Coastguard Worker // b/37247891, the loop can be unrolled, but should handle the (unlikely, but clearly 349*795d594fSAndroid Build Coastguard Worker // not impossible) environment uses of the terminating condition in a correct manner. envUsesInCond()350*795d594fSAndroid Build Coastguard Worker private static void envUsesInCond() { 351*795d594fSAndroid Build Coastguard Worker boolean x = false; 352*795d594fSAndroid Build Coastguard Worker for (int i = 0; !(x = i >= 1); i++) { 353*795d594fSAndroid Build Coastguard Worker $noinline$foo(true, i); 354*795d594fSAndroid Build Coastguard Worker } 355*795d594fSAndroid Build Coastguard Worker } 356*795d594fSAndroid Build Coastguard Worker 357*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.oneBoth(short[], char[]) loop_optimization (before) 358*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 359*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 360*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<One>>] loop:<<Loop>> outer_loop:none 361*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<One>>] loop:<<Loop>> outer_loop:none 362*795d594fSAndroid Build Coastguard Worker // 363*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: void Main.oneBoth(short[], char[]) loop_optimization (after) 364*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 365*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>] loop:none 366*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi:i\d+>>,<<Repl>>] loop:<<Loop:B\d+>> outer_loop:none 367*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Repl>>] loop:<<Loop>> outer_loop:none 368*795d594fSAndroid Build Coastguard Worker // 369*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: void Main.oneBoth(short[], char[]) loop_optimization (after) 370*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 371*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 372*795d594fSAndroid Build Coastguard Worker // 373*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>,{{j\d+}}] loop:none 374*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LoopP:j\d+>> VecPredWhile loop:<<Loop:B\d+>> outer_loop:none 375*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi:i\d+>>,<<Repl>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 376*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Repl>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 377*795d594fSAndroid Build Coastguard Worker // 378*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 379*795d594fSAndroid Build Coastguard Worker // 380*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>] loop:none 381*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi:i\d+>>,<<Repl>>] loop:<<Loop:B\d+>> outer_loop:none 382*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Repl>>] loop:<<Loop>> outer_loop:none 383*795d594fSAndroid Build Coastguard Worker // 384*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: 385*795d594fSAndroid Build Coastguard Worker // 386*795d594fSAndroid Build Coastguard Worker // Bug b/37764324: integral same-length packed types can be mixed freely. oneBoth(short[] a, char[] b)387*795d594fSAndroid Build Coastguard Worker private static void oneBoth(short[] a, char[] b) { 388*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < Math.min(a.length, b.length); i++) { 389*795d594fSAndroid Build Coastguard Worker a[i] = 1; 390*795d594fSAndroid Build Coastguard Worker b[i] = 1; 391*795d594fSAndroid Build Coastguard Worker } 392*795d594fSAndroid Build Coastguard Worker } 393*795d594fSAndroid Build Coastguard Worker 394*795d594fSAndroid Build Coastguard Worker // Bug b/37768917: potential dynamic BCE vs. loop optimizations 395*795d594fSAndroid Build Coastguard Worker // case should be deal with correctly (used to DCHECK fail). arrayInTripCount(int[] a, byte[] b, int n)396*795d594fSAndroid Build Coastguard Worker private static void arrayInTripCount(int[] a, byte[] b, int n) { 397*795d594fSAndroid Build Coastguard Worker for (int k = 0; k < n; k++) { 398*795d594fSAndroid Build Coastguard Worker for (int i = 0, u = a[0]; i < u; i++) { 399*795d594fSAndroid Build Coastguard Worker b[i] += 2; 400*795d594fSAndroid Build Coastguard Worker } 401*795d594fSAndroid Build Coastguard Worker } 402*795d594fSAndroid Build Coastguard Worker } 403*795d594fSAndroid Build Coastguard Worker 404*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.typeConv(byte[], byte[]) loop_optimization (before) 405*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 406*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 407*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Get:b\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none 408*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<One>>] loop:<<Loop>> outer_loop:none 409*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Add>>] loop:<<Loop>> outer_loop:none 410*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 411*795d594fSAndroid Build Coastguard Worker // 412*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: void Main.typeConv(byte[], byte[]) loop_optimization (after) 413*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 414*795d594fSAndroid Build Coastguard Worker 415*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>] loop:none 416*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<Phi1:i\d+>>] loop:<<Loop1:B\d+>> outer_loop:none 417*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Vadd:d\d+>> VecAdd [<<Load>>,<<Repl>>] loop:<<Loop1>> outer_loop:none 418*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi1>>,<<Vadd>>] loop:<<Loop1>> outer_loop:none 419*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Get:b\d+>> ArrayGet [{{l\d+}},<<Phi2:i\d+>>] loop:<<Loop2:B\d+>> outer_loop:none 420*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<One>>] loop:<<Loop2>> outer_loop:none 421*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Add>>] loop:<<Loop2>> outer_loop:none 422*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi2>>,<<Cnv>>] loop:<<Loop2>> outer_loop:none 423*795d594fSAndroid Build Coastguard Worker // 424*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: void Main.typeConv(byte[], byte[]) loop_optimization (after) 425*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<One:i\d+>> IntConstant 1 loop:none 426*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 427*795d594fSAndroid Build Coastguard Worker // 428*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>,{{j\d+}}] loop:none 429*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LoopP:j\d+>> VecPredWhile loop:<<Loop1:B\d+>> outer_loop:none 430*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<Phi1:i\d+>>,<<LoopP>>] loop:<<Loop1>> outer_loop:none 431*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Vadd:d\d+>> VecAdd [<<Load>>,<<Repl>>,<<LoopP>>] loop:<<Loop1>> outer_loop:none 432*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi1>>,<<Vadd>>,<<LoopP>>] loop:<<Loop1>> outer_loop:none 433*795d594fSAndroid Build Coastguard Worker // 434*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 435*795d594fSAndroid Build Coastguard Worker // 436*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<One>>] loop:none 437*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<Phi1:i\d+>>] loop:<<Loop1:B\d+>> outer_loop:none 438*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Vadd:d\d+>> VecAdd [<<Load>>,<<Repl>>] loop:<<Loop1>> outer_loop:none 439*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore [{{l\d+}},<<Phi1>>,<<Vadd>>] loop:<<Loop1>> outer_loop:none 440*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Get:b\d+>> ArrayGet [{{l\d+}},<<Phi2:i\d+>>] loop:<<Loop2:B\d+>> outer_loop:none 441*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<One>>] loop:<<Loop2>> outer_loop:none 442*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Add>>] loop:<<Loop2>> outer_loop:none 443*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi2>>,<<Cnv>>] loop:<<Loop2>> outer_loop:none 444*795d594fSAndroid Build Coastguard Worker // 445*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: 446*795d594fSAndroid Build Coastguard Worker // 447*795d594fSAndroid Build Coastguard Worker // Scalar code in cleanup loop uses correct byte type on array get and type conversion. typeConv(byte[] a, byte[] b)448*795d594fSAndroid Build Coastguard Worker private static void typeConv(byte[] a, byte[] b) { 449*795d594fSAndroid Build Coastguard Worker int len = Math.min(a.length, b.length); 450*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < len; i++) { 451*795d594fSAndroid Build Coastguard Worker a[i] = (byte) (b[i] + 1); 452*795d594fSAndroid Build Coastguard Worker } 453*795d594fSAndroid Build Coastguard Worker } 454*795d594fSAndroid Build Coastguard Worker 455*795d594fSAndroid Build Coastguard Worker // Environment of an instruction, removed during SimplifyInduction, should be adjusted. 456*795d594fSAndroid Build Coastguard Worker // 457*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inductionMax(int[]) loop_optimization (before) 458*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 459*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 460*795d594fSAndroid Build Coastguard Worker // 461*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.inductionMax(int[]) loop_optimization (after) 462*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi inductionMax(int[] a)463*795d594fSAndroid Build Coastguard Worker private static void inductionMax(int[] a) { 464*795d594fSAndroid Build Coastguard Worker int s = 0; 465*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 466*795d594fSAndroid Build Coastguard Worker s = Math.max(s, 5); 467*795d594fSAndroid Build Coastguard Worker } 468*795d594fSAndroid Build Coastguard Worker } 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.feedsIntoDeopt(int[]) loop_optimization (before) 471*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 472*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none 473*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:none 474*795d594fSAndroid Build Coastguard Worker // 475*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 476*795d594fSAndroid Build Coastguard Worker // 477*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.feedsIntoDeopt(int[]) loop_optimization (after) 478*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 479*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi feedsIntoDeopt(int[] a)480*795d594fSAndroid Build Coastguard Worker static int feedsIntoDeopt(int[] a) { 481*795d594fSAndroid Build Coastguard Worker // Reduction should be removed. 482*795d594fSAndroid Build Coastguard Worker int r = 0; 483*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 484*795d594fSAndroid Build Coastguard Worker r += 10; 485*795d594fSAndroid Build Coastguard Worker } 486*795d594fSAndroid Build Coastguard Worker // Even though uses feed into deopts of BCE. 487*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < 100; i++) { 488*795d594fSAndroid Build Coastguard Worker a[i] = a[i - 1]; 489*795d594fSAndroid Build Coastguard Worker } 490*795d594fSAndroid Build Coastguard Worker return r; 491*795d594fSAndroid Build Coastguard Worker } 492*795d594fSAndroid Build Coastguard Worker absCanBeNegative(int x)493*795d594fSAndroid Build Coastguard Worker static int absCanBeNegative(int x) { 494*795d594fSAndroid Build Coastguard Worker int a[] = { 1, 2, 3 }; 495*795d594fSAndroid Build Coastguard Worker int y = 0; 496*795d594fSAndroid Build Coastguard Worker for (int i = Math.abs(x); i < a.length; i++) { 497*795d594fSAndroid Build Coastguard Worker y += a[i]; 498*795d594fSAndroid Build Coastguard Worker } 499*795d594fSAndroid Build Coastguard Worker return y; 500*795d594fSAndroid Build Coastguard Worker } 501*795d594fSAndroid Build Coastguard Worker 502*795d594fSAndroid Build Coastguard Worker // b/65478356: sum up 2-dim array. sum(int[][] a)503*795d594fSAndroid Build Coastguard Worker static int sum(int[][] a) { 504*795d594fSAndroid Build Coastguard Worker int sum = 0; 505*795d594fSAndroid Build Coastguard Worker for (int y = 0; y < a.length; y++) { 506*795d594fSAndroid Build Coastguard Worker int[] aa = a[y]; 507*795d594fSAndroid Build Coastguard Worker for (int x = 0; x < aa.length; x++) { 508*795d594fSAndroid Build Coastguard Worker sum += aa[x]; 509*795d594fSAndroid Build Coastguard Worker } 510*795d594fSAndroid Build Coastguard Worker } 511*795d594fSAndroid Build Coastguard Worker return sum; 512*795d594fSAndroid Build Coastguard Worker } 513*795d594fSAndroid Build Coastguard Worker 514*795d594fSAndroid Build Coastguard Worker // Large loop body should not break unrolling computation. largeBody(int[] x)515*795d594fSAndroid Build Coastguard Worker static void largeBody(int[] x) { 516*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 517*795d594fSAndroid Build Coastguard Worker x[i] = x[i] * 1 + x[i] * 2 + x[i] * 3 + x[i] * 4 + x[i] * 5 + x[i] * 6 + 518*795d594fSAndroid Build Coastguard Worker x[i] * 7 + x[i] * 8 + x[i] * 9 + x[i] * 10 + x[i] * 11 + x[i] * 12 + 519*795d594fSAndroid Build Coastguard Worker x[i] * 13 + x[i] * 14 + x[i] * 15 + x[i] * 1 + x[i] * 2 + x[i] * 3 + x[i] * 4 + 520*795d594fSAndroid Build Coastguard Worker x[i] * 5 + x[i] * 6 + x[i] * 7 + x[i] * 8 + x[i] * 9 + x[i] * 10 + x[i] * 11 + 521*795d594fSAndroid Build Coastguard Worker x[i] * 12 + x[i] * 13 + x[i] * 14 + x[i] * 15 + x[i] * 1 + x[i] * 2 + x[i] * 3 + 522*795d594fSAndroid Build Coastguard Worker x[i] * 4 + x[i] * 5; 523*795d594fSAndroid Build Coastguard Worker } 524*795d594fSAndroid Build Coastguard Worker } 525*795d594fSAndroid Build Coastguard Worker 526*795d594fSAndroid Build Coastguard Worker // Mixed of 16-bit and 8-bit array references. castAndNarrow(byte[] x, char[] y)527*795d594fSAndroid Build Coastguard Worker static void castAndNarrow(byte[] x, char[] y) { 528*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 529*795d594fSAndroid Build Coastguard Worker x[i] = (byte) ((short) y[i] + 1); 530*795d594fSAndroid Build Coastguard Worker } 531*795d594fSAndroid Build Coastguard Worker } 532*795d594fSAndroid Build Coastguard Worker 533*795d594fSAndroid Build Coastguard Worker // Avoid bad scheduler-SIMD interaction. doNotMoveSIMD()534*795d594fSAndroid Build Coastguard Worker static int doNotMoveSIMD() { 535*795d594fSAndroid Build Coastguard Worker int sum = 0; 536*795d594fSAndroid Build Coastguard Worker for (int j = 0; j <= 8; j++) { 537*795d594fSAndroid Build Coastguard Worker int[] a = new int[17]; // a[i] = 0; 538*795d594fSAndroid Build Coastguard Worker // ConstructorFence ? 539*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 540*795d594fSAndroid Build Coastguard Worker a[i] += 1; // a[i] = 1; 541*795d594fSAndroid Build Coastguard Worker } 542*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 543*795d594fSAndroid Build Coastguard Worker sum += a[i]; // expect a[i] = 1; 544*795d594fSAndroid Build Coastguard Worker } 545*795d594fSAndroid Build Coastguard Worker } 546*795d594fSAndroid Build Coastguard Worker return sum; 547*795d594fSAndroid Build Coastguard Worker } 548*795d594fSAndroid Build Coastguard Worker 549*795d594fSAndroid Build Coastguard Worker // Ensure spilling saves full SIMD values. reduction32Values(int[] a, int[] b, int[] c, int[] d)550*795d594fSAndroid Build Coastguard Worker private static final int reduction32Values(int[] a, int[] b, int[] c, int[] d) { 551*795d594fSAndroid Build Coastguard Worker int s0 = 0; 552*795d594fSAndroid Build Coastguard Worker int s1 = 0; 553*795d594fSAndroid Build Coastguard Worker int s2 = 0; 554*795d594fSAndroid Build Coastguard Worker int s3 = 0; 555*795d594fSAndroid Build Coastguard Worker int s4 = 0; 556*795d594fSAndroid Build Coastguard Worker int s5 = 0; 557*795d594fSAndroid Build Coastguard Worker int s6 = 0; 558*795d594fSAndroid Build Coastguard Worker int s7 = 0; 559*795d594fSAndroid Build Coastguard Worker int s8 = 0; 560*795d594fSAndroid Build Coastguard Worker int s9 = 0; 561*795d594fSAndroid Build Coastguard Worker int s10 = 0; 562*795d594fSAndroid Build Coastguard Worker int s11 = 0; 563*795d594fSAndroid Build Coastguard Worker int s12 = 0; 564*795d594fSAndroid Build Coastguard Worker int s13 = 0; 565*795d594fSAndroid Build Coastguard Worker int s14 = 0; 566*795d594fSAndroid Build Coastguard Worker int s15 = 0; 567*795d594fSAndroid Build Coastguard Worker int s16 = 0; 568*795d594fSAndroid Build Coastguard Worker int s17 = 0; 569*795d594fSAndroid Build Coastguard Worker int s18 = 0; 570*795d594fSAndroid Build Coastguard Worker int s19 = 0; 571*795d594fSAndroid Build Coastguard Worker int s20 = 0; 572*795d594fSAndroid Build Coastguard Worker int s21 = 0; 573*795d594fSAndroid Build Coastguard Worker int s22 = 0; 574*795d594fSAndroid Build Coastguard Worker int s23 = 0; 575*795d594fSAndroid Build Coastguard Worker int s24 = 0; 576*795d594fSAndroid Build Coastguard Worker int s25 = 0; 577*795d594fSAndroid Build Coastguard Worker int s26 = 0; 578*795d594fSAndroid Build Coastguard Worker int s27 = 0; 579*795d594fSAndroid Build Coastguard Worker int s28 = 0; 580*795d594fSAndroid Build Coastguard Worker int s29 = 0; 581*795d594fSAndroid Build Coastguard Worker int s30 = 0; 582*795d594fSAndroid Build Coastguard Worker int s31 = 0; 583*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < 100; i++) { 584*795d594fSAndroid Build Coastguard Worker s0 += a[i]; 585*795d594fSAndroid Build Coastguard Worker s1 += b[i]; 586*795d594fSAndroid Build Coastguard Worker s2 += c[i]; 587*795d594fSAndroid Build Coastguard Worker s3 += d[i]; 588*795d594fSAndroid Build Coastguard Worker s4 += a[i]; 589*795d594fSAndroid Build Coastguard Worker s5 += b[i]; 590*795d594fSAndroid Build Coastguard Worker s6 += c[i]; 591*795d594fSAndroid Build Coastguard Worker s7 += d[i]; 592*795d594fSAndroid Build Coastguard Worker s8 += a[i]; 593*795d594fSAndroid Build Coastguard Worker s9 += b[i]; 594*795d594fSAndroid Build Coastguard Worker s10 += c[i]; 595*795d594fSAndroid Build Coastguard Worker s11 += d[i]; 596*795d594fSAndroid Build Coastguard Worker s12 += a[i]; 597*795d594fSAndroid Build Coastguard Worker s13 += b[i]; 598*795d594fSAndroid Build Coastguard Worker s14 += c[i]; 599*795d594fSAndroid Build Coastguard Worker s15 += d[i]; 600*795d594fSAndroid Build Coastguard Worker s16 += a[i]; 601*795d594fSAndroid Build Coastguard Worker s17 += b[i]; 602*795d594fSAndroid Build Coastguard Worker s18 += c[i]; 603*795d594fSAndroid Build Coastguard Worker s19 += d[i]; 604*795d594fSAndroid Build Coastguard Worker s20 += a[i]; 605*795d594fSAndroid Build Coastguard Worker s21 += b[i]; 606*795d594fSAndroid Build Coastguard Worker s22 += c[i]; 607*795d594fSAndroid Build Coastguard Worker s23 += d[i]; 608*795d594fSAndroid Build Coastguard Worker s24 += a[i]; 609*795d594fSAndroid Build Coastguard Worker s25 += b[i]; 610*795d594fSAndroid Build Coastguard Worker s26 += c[i]; 611*795d594fSAndroid Build Coastguard Worker s27 += d[i]; 612*795d594fSAndroid Build Coastguard Worker s28 += a[i]; 613*795d594fSAndroid Build Coastguard Worker s29 += b[i]; 614*795d594fSAndroid Build Coastguard Worker s30 += c[i]; 615*795d594fSAndroid Build Coastguard Worker s31 += d[i]; 616*795d594fSAndroid Build Coastguard Worker } 617*795d594fSAndroid Build Coastguard Worker return s0 + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15 + 618*795d594fSAndroid Build Coastguard Worker s16 + s17 + s18 + s19 + s20 + s21 + s22 + s23 + 619*795d594fSAndroid Build Coastguard Worker s24 + s25 + s26 + s27 + s28 + s29 + s30 + s31; 620*795d594fSAndroid Build Coastguard Worker } 621*795d594fSAndroid Build Coastguard Worker 622*795d594fSAndroid Build Coastguard Worker // Ensure spilling saves regular FP values correctly when the graph HasSIMD() 623*795d594fSAndroid Build Coastguard Worker // is true. 624*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: float Main.$noinline$ensureSlowPathFPSpillFill(float[], float[], float[], float[], int[]) loop_optimization (after) 625*795d594fSAndroid Build Coastguard Worker // 626*795d594fSAndroid Build Coastguard Worker // Both regular and SIMD accesses are present. 627*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecLoad 628*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet $noinline$ensureSlowPathFPSpillFill(float[] a, float[] b, float[] c, float[] d, int[] e)629*795d594fSAndroid Build Coastguard Worker private static final float $noinline$ensureSlowPathFPSpillFill(float[] a, 630*795d594fSAndroid Build Coastguard Worker float[] b, 631*795d594fSAndroid Build Coastguard Worker float[] c, 632*795d594fSAndroid Build Coastguard Worker float[] d, 633*795d594fSAndroid Build Coastguard Worker int[] e) { 634*795d594fSAndroid Build Coastguard Worker // This loop should be vectorized so the graph->HasSIMD() will be true. 635*795d594fSAndroid Build Coastguard Worker // A power-of-2 number of iterations is chosen to avoid peeling/unrolling interference. 636*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 64; i++) { 637*795d594fSAndroid Build Coastguard Worker // The actual values of the array elements don't matter, just the 638*795d594fSAndroid Build Coastguard Worker // presence of a SIMD loop. 639*795d594fSAndroid Build Coastguard Worker e[i]++; 640*795d594fSAndroid Build Coastguard Worker } 641*795d594fSAndroid Build Coastguard Worker 642*795d594fSAndroid Build Coastguard Worker float f0 = 0; 643*795d594fSAndroid Build Coastguard Worker float f1 = 0; 644*795d594fSAndroid Build Coastguard Worker float f2 = 0; 645*795d594fSAndroid Build Coastguard Worker float f3 = 0; 646*795d594fSAndroid Build Coastguard Worker float f4 = 0; 647*795d594fSAndroid Build Coastguard Worker float f5 = 0; 648*795d594fSAndroid Build Coastguard Worker float f6 = 0; 649*795d594fSAndroid Build Coastguard Worker float f7 = 0; 650*795d594fSAndroid Build Coastguard Worker float f8 = 0; 651*795d594fSAndroid Build Coastguard Worker float f9 = 0; 652*795d594fSAndroid Build Coastguard Worker float f10 = 0; 653*795d594fSAndroid Build Coastguard Worker float f11 = 0; 654*795d594fSAndroid Build Coastguard Worker float f12 = 0; 655*795d594fSAndroid Build Coastguard Worker float f13 = 0; 656*795d594fSAndroid Build Coastguard Worker float f14 = 0; 657*795d594fSAndroid Build Coastguard Worker float f15 = 0; 658*795d594fSAndroid Build Coastguard Worker float f16 = 0; 659*795d594fSAndroid Build Coastguard Worker float f17 = 0; 660*795d594fSAndroid Build Coastguard Worker float f18 = 0; 661*795d594fSAndroid Build Coastguard Worker float f19 = 0; 662*795d594fSAndroid Build Coastguard Worker float f20 = 0; 663*795d594fSAndroid Build Coastguard Worker float f21 = 0; 664*795d594fSAndroid Build Coastguard Worker float f22 = 0; 665*795d594fSAndroid Build Coastguard Worker float f23 = 0; 666*795d594fSAndroid Build Coastguard Worker float f24 = 0; 667*795d594fSAndroid Build Coastguard Worker float f25 = 0; 668*795d594fSAndroid Build Coastguard Worker float f26 = 0; 669*795d594fSAndroid Build Coastguard Worker float f27 = 0; 670*795d594fSAndroid Build Coastguard Worker float f28 = 0; 671*795d594fSAndroid Build Coastguard Worker float f29 = 0; 672*795d594fSAndroid Build Coastguard Worker float f30 = 0; 673*795d594fSAndroid Build Coastguard Worker float f31 = 0; 674*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 675*795d594fSAndroid Build Coastguard Worker f0 += a[i]; 676*795d594fSAndroid Build Coastguard Worker f1 += b[i]; 677*795d594fSAndroid Build Coastguard Worker f2 += c[i]; 678*795d594fSAndroid Build Coastguard Worker f3 += d[i]; 679*795d594fSAndroid Build Coastguard Worker f4 += a[i]; 680*795d594fSAndroid Build Coastguard Worker f5 += b[i]; 681*795d594fSAndroid Build Coastguard Worker f6 += c[i]; 682*795d594fSAndroid Build Coastguard Worker f7 += d[i]; 683*795d594fSAndroid Build Coastguard Worker f8 += a[i]; 684*795d594fSAndroid Build Coastguard Worker f9 += b[i]; 685*795d594fSAndroid Build Coastguard Worker f10 += c[i]; 686*795d594fSAndroid Build Coastguard Worker f11 += d[i]; 687*795d594fSAndroid Build Coastguard Worker f12 += a[i]; 688*795d594fSAndroid Build Coastguard Worker f13 += b[i]; 689*795d594fSAndroid Build Coastguard Worker f14 += c[i]; 690*795d594fSAndroid Build Coastguard Worker f15 += d[i]; 691*795d594fSAndroid Build Coastguard Worker f16 += a[i]; 692*795d594fSAndroid Build Coastguard Worker f17 += b[i]; 693*795d594fSAndroid Build Coastguard Worker f18 += c[i]; 694*795d594fSAndroid Build Coastguard Worker f19 += d[i]; 695*795d594fSAndroid Build Coastguard Worker f20 += a[i]; 696*795d594fSAndroid Build Coastguard Worker f21 += b[i]; 697*795d594fSAndroid Build Coastguard Worker f22 += c[i]; 698*795d594fSAndroid Build Coastguard Worker f23 += d[i]; 699*795d594fSAndroid Build Coastguard Worker f24 += a[i]; 700*795d594fSAndroid Build Coastguard Worker f25 += b[i]; 701*795d594fSAndroid Build Coastguard Worker f26 += c[i]; 702*795d594fSAndroid Build Coastguard Worker f27 += d[i]; 703*795d594fSAndroid Build Coastguard Worker f28 += a[i]; 704*795d594fSAndroid Build Coastguard Worker f29 += b[i]; 705*795d594fSAndroid Build Coastguard Worker f30 += c[i]; 706*795d594fSAndroid Build Coastguard Worker f31 += d[i]; 707*795d594fSAndroid Build Coastguard Worker } 708*795d594fSAndroid Build Coastguard Worker return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15 + 709*795d594fSAndroid Build Coastguard Worker f16 + f17 + f18 + f19 + f20 + f21 + f22 + f23 + 710*795d594fSAndroid Build Coastguard Worker f24 + f25 + f26 + f27 + f28 + f29 + f30 + f31; 711*795d594fSAndroid Build Coastguard Worker } 712*795d594fSAndroid Build Coastguard Worker reductionIntoReplication()713*795d594fSAndroid Build Coastguard Worker public static int reductionIntoReplication() { 714*795d594fSAndroid Build Coastguard Worker int[] a = { 1, 2, 3, 4 }; 715*795d594fSAndroid Build Coastguard Worker int x = 0; 716*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 717*795d594fSAndroid Build Coastguard Worker x += a[i]; 718*795d594fSAndroid Build Coastguard Worker } 719*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 720*795d594fSAndroid Build Coastguard Worker a[i] = x; 721*795d594fSAndroid Build Coastguard Worker } 722*795d594fSAndroid Build Coastguard Worker return a[3]; 723*795d594fSAndroid Build Coastguard Worker } 724*795d594fSAndroid Build Coastguard Worker 725*795d594fSAndroid Build Coastguard Worker // Dot product and SAD vectorization idioms used to have a bug when some 726*795d594fSAndroid Build Coastguard Worker // instruction in the loop was visited twice causing a compiler crash. 727*795d594fSAndroid Build Coastguard Worker // It happened when two vectorization idioms' matched patterns had a common 728*795d594fSAndroid Build Coastguard Worker // sub-expression. 729*795d594fSAndroid Build Coastguard Worker 730*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: DotProduct and ArraySet. 731*795d594fSAndroid Build Coastguard Worker // 732*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testDotProdAndSet(byte[], byte[], byte[]) loop_optimization (after) 733*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 734*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore testDotProdAndSet(byte[] a, byte[] b, byte[] c)735*795d594fSAndroid Build Coastguard Worker public static final int testDotProdAndSet(byte[] a, byte[] b, byte[] c) { 736*795d594fSAndroid Build Coastguard Worker int s = 1; 737*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < b.length; i++) { 738*795d594fSAndroid Build Coastguard Worker int temp = a[i] * b[i]; 739*795d594fSAndroid Build Coastguard Worker c[i]= (byte)temp; 740*795d594fSAndroid Build Coastguard Worker s += temp; 741*795d594fSAndroid Build Coastguard Worker } 742*795d594fSAndroid Build Coastguard Worker return s - 1; 743*795d594fSAndroid Build Coastguard Worker } 744*795d594fSAndroid Build Coastguard Worker 745*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: DotProduct and DotProduct. 746*795d594fSAndroid Build Coastguard Worker // 747*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testDotProdAndDotProd(byte[], byte[]) loop_optimization (after) 748*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 749*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd testDotProdAndDotProd(byte[] a, byte[] b)750*795d594fSAndroid Build Coastguard Worker public static final int testDotProdAndDotProd(byte[] a, byte[] b) { 751*795d594fSAndroid Build Coastguard Worker int s0 = 1; 752*795d594fSAndroid Build Coastguard Worker int s1 = 1; 753*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < b.length; i++) { 754*795d594fSAndroid Build Coastguard Worker int temp = a[i] * b[i]; 755*795d594fSAndroid Build Coastguard Worker s0 += temp; 756*795d594fSAndroid Build Coastguard Worker s1 += temp; 757*795d594fSAndroid Build Coastguard Worker } 758*795d594fSAndroid Build Coastguard Worker return s0 + s1; 759*795d594fSAndroid Build Coastguard Worker } 760*795d594fSAndroid Build Coastguard Worker 761*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and ArraySet. 762*795d594fSAndroid Build Coastguard Worker // 763*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.testSADAndSet(int[], int[], int[]) loop_optimization (after) 764*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 765*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore 766*795d594fSAndroid Build Coastguard Worker // 767*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndSet(int[], int[], int[]) loop_optimization (after) 768*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 769*795d594fSAndroid Build Coastguard Worker // 770*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 771*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 772*795d594fSAndroid Build Coastguard Worker // 773*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 774*795d594fSAndroid Build Coastguard Worker // 775*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 776*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecStore 777*795d594fSAndroid Build Coastguard Worker // 778*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndSet(int[] x, int[] y, int[] z)779*795d594fSAndroid Build Coastguard Worker public static int testSADAndSet(int[] x, int[] y, int[] z) { 780*795d594fSAndroid Build Coastguard Worker int min_length = Math.min(x.length, y.length); 781*795d594fSAndroid Build Coastguard Worker int sad = 0; 782*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < min_length; i++) { 783*795d594fSAndroid Build Coastguard Worker int temp = Math.abs(x[i] - y[i]); 784*795d594fSAndroid Build Coastguard Worker z[i] = temp; 785*795d594fSAndroid Build Coastguard Worker sad += temp; 786*795d594fSAndroid Build Coastguard Worker } 787*795d594fSAndroid Build Coastguard Worker return sad; 788*795d594fSAndroid Build Coastguard Worker } 789*795d594fSAndroid Build Coastguard Worker 790*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and SAD. 791*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.testSADAndSAD(int[], int[]) loop_optimization (after) 792*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 793*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 794*795d594fSAndroid Build Coastguard Worker // 795*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndSAD(int[], int[]) loop_optimization (after) 796*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 797*795d594fSAndroid Build Coastguard Worker // 798*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 799*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 800*795d594fSAndroid Build Coastguard Worker // 801*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 802*795d594fSAndroid Build Coastguard Worker // 803*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 804*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 805*795d594fSAndroid Build Coastguard Worker // 806*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndSAD(int[] x, int[] y)807*795d594fSAndroid Build Coastguard Worker public static final int testSADAndSAD(int[] x, int[] y) { 808*795d594fSAndroid Build Coastguard Worker int s0 = 1; 809*795d594fSAndroid Build Coastguard Worker int s1 = 1; 810*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 811*795d594fSAndroid Build Coastguard Worker int temp = Math.abs(x[i] - y[i]); 812*795d594fSAndroid Build Coastguard Worker s0 += temp; 813*795d594fSAndroid Build Coastguard Worker s1 += temp; 814*795d594fSAndroid Build Coastguard Worker } 815*795d594fSAndroid Build Coastguard Worker return s0 + s1; 816*795d594fSAndroid Build Coastguard Worker } 817*795d594fSAndroid Build Coastguard Worker 818*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: DotProd and DotProd with extra mul. 819*795d594fSAndroid Build Coastguard Worker // 820*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testDotProdAndDotProdExtraMul0(byte[], byte[]) loop_optimization (after) 821*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecMul 822*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 823*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd testDotProdAndDotProdExtraMul0(byte[] a, byte[] b)824*795d594fSAndroid Build Coastguard Worker public static final int testDotProdAndDotProdExtraMul0(byte[] a, byte[] b) { 825*795d594fSAndroid Build Coastguard Worker int s0 = 1; 826*795d594fSAndroid Build Coastguard Worker int s1 = 1; 827*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < b.length; i++) { 828*795d594fSAndroid Build Coastguard Worker int temp0 = a[i] * b[i]; 829*795d594fSAndroid Build Coastguard Worker int temp1 = (byte)(temp0) * a[i]; 830*795d594fSAndroid Build Coastguard Worker s0 += temp1; 831*795d594fSAndroid Build Coastguard Worker s1 += temp0; 832*795d594fSAndroid Build Coastguard Worker } 833*795d594fSAndroid Build Coastguard Worker return s0 + s1; 834*795d594fSAndroid Build Coastguard Worker } 835*795d594fSAndroid Build Coastguard Worker 836*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: DotProd and DotProd with extra mul (reversed order). 837*795d594fSAndroid Build Coastguard Worker // 838*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testDotProdAndDotProdExtraMul1(byte[], byte[]) loop_optimization (after) 839*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecMul 840*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 841*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd testDotProdAndDotProdExtraMul1(byte[] a, byte[] b)842*795d594fSAndroid Build Coastguard Worker public static final int testDotProdAndDotProdExtraMul1(byte[] a, byte[] b) { 843*795d594fSAndroid Build Coastguard Worker int s0 = 1; 844*795d594fSAndroid Build Coastguard Worker int s1 = 1; 845*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < b.length; i++) { 846*795d594fSAndroid Build Coastguard Worker int temp0 = a[i] * b[i]; 847*795d594fSAndroid Build Coastguard Worker int temp1 = (byte)(temp0) * a[i]; 848*795d594fSAndroid Build Coastguard Worker s0 += temp0; 849*795d594fSAndroid Build Coastguard Worker s1 += temp1; 850*795d594fSAndroid Build Coastguard Worker } 851*795d594fSAndroid Build Coastguard Worker return s0 + s1; 852*795d594fSAndroid Build Coastguard Worker } 853*795d594fSAndroid Build Coastguard Worker 854*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and SAD with extra abs. 855*795d594fSAndroid Build Coastguard Worker // 856*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.testSADAndSADExtraAbs0(int[], int[]) loop_optimization (after) 857*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 858*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecAbs 859*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 860*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 861*795d594fSAndroid Build Coastguard Worker // 862*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndSADExtraAbs0(int[], int[]) loop_optimization (after) 863*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 864*795d594fSAndroid Build Coastguard Worker // 865*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 866*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 867*795d594fSAndroid Build Coastguard Worker // 868*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 869*795d594fSAndroid Build Coastguard Worker // 870*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 871*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecAbs 872*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 873*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 874*795d594fSAndroid Build Coastguard Worker // 875*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndSADExtraAbs0(int[] x, int[] y)876*795d594fSAndroid Build Coastguard Worker public static final int testSADAndSADExtraAbs0(int[] x, int[] y) { 877*795d594fSAndroid Build Coastguard Worker int s0 = 1; 878*795d594fSAndroid Build Coastguard Worker int s1 = 1; 879*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 880*795d594fSAndroid Build Coastguard Worker int temp0 = Math.abs(x[i] - y[i]); 881*795d594fSAndroid Build Coastguard Worker int temp1 = Math.abs(temp0 - y[i]); 882*795d594fSAndroid Build Coastguard Worker s0 += temp1; 883*795d594fSAndroid Build Coastguard Worker s1 += temp0; 884*795d594fSAndroid Build Coastguard Worker } 885*795d594fSAndroid Build Coastguard Worker return s0 + s1; 886*795d594fSAndroid Build Coastguard Worker } 887*795d594fSAndroid Build Coastguard Worker 888*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and SAD with extra abs (reversed order). 889*795d594fSAndroid Build Coastguard Worker // 890*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM: int Main.testSADAndSADExtraAbs1(int[], int[]) loop_optimization (after) 891*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 892*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecAbs 893*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 894*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 895*795d594fSAndroid Build Coastguard Worker // 896*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndSADExtraAbs1(int[], int[]) loop_optimization (after) 897*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 898*795d594fSAndroid Build Coastguard Worker // 899*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 900*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 901*795d594fSAndroid Build Coastguard Worker // 902*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 903*795d594fSAndroid Build Coastguard Worker // 904*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 905*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecAbs 906*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 907*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 908*795d594fSAndroid Build Coastguard Worker // 909*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndSADExtraAbs1(int[] x, int[] y)910*795d594fSAndroid Build Coastguard Worker public static final int testSADAndSADExtraAbs1(int[] x, int[] y) { 911*795d594fSAndroid Build Coastguard Worker int s0 = 1; 912*795d594fSAndroid Build Coastguard Worker int s1 = 1; 913*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 914*795d594fSAndroid Build Coastguard Worker int temp0 = Math.abs(x[i] - y[i]); 915*795d594fSAndroid Build Coastguard Worker int temp1 = Math.abs(temp0 - y[i]); 916*795d594fSAndroid Build Coastguard Worker s0 += temp0; 917*795d594fSAndroid Build Coastguard Worker s1 += temp1; 918*795d594fSAndroid Build Coastguard Worker } 919*795d594fSAndroid Build Coastguard Worker return s0 + s1; 920*795d594fSAndroid Build Coastguard Worker } 921*795d594fSAndroid Build Coastguard Worker 922*795d594fSAndroid Build Coastguard Worker 923*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and DotProd combined. 924*795d594fSAndroid Build Coastguard Worker // 925*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndDotProdCombined0(byte[], byte[]) loop_optimization (after) 926*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 927*795d594fSAndroid Build Coastguard Worker // 928*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 929*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 930*795d594fSAndroid Build Coastguard Worker // 931*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 932*795d594fSAndroid Build Coastguard Worker // 933*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 934*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 935*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 936*795d594fSAndroid Build Coastguard Worker // 937*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndDotProdCombined0(byte[] x, byte[] y)938*795d594fSAndroid Build Coastguard Worker public static final int testSADAndDotProdCombined0(byte[] x, byte[] y) { 939*795d594fSAndroid Build Coastguard Worker int s0 = 1; 940*795d594fSAndroid Build Coastguard Worker int s1 = 1; 941*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 942*795d594fSAndroid Build Coastguard Worker int temp0 = x[i] - y[i]; 943*795d594fSAndroid Build Coastguard Worker int temp1 = Math.abs(temp0); 944*795d594fSAndroid Build Coastguard Worker int temp2 = x[i] * (byte)(temp0); 945*795d594fSAndroid Build Coastguard Worker 946*795d594fSAndroid Build Coastguard Worker s0 += temp1; 947*795d594fSAndroid Build Coastguard Worker s1 += temp2; 948*795d594fSAndroid Build Coastguard Worker } 949*795d594fSAndroid Build Coastguard Worker return s0 + s1; 950*795d594fSAndroid Build Coastguard Worker } 951*795d594fSAndroid Build Coastguard Worker 952*795d594fSAndroid Build Coastguard Worker // Idioms common sub-expression bug: SAD and DotProd combined (reversed order). 953*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: int Main.testSADAndDotProdCombined1(byte[], byte[]) loop_optimization (after) 954*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 955*795d594fSAndroid Build Coastguard Worker // 956*795d594fSAndroid Build Coastguard Worker // VecSADAccumulate is not supported for SVE. 957*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: VecSADAccumulate 958*795d594fSAndroid Build Coastguard Worker // 959*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 960*795d594fSAndroid Build Coastguard Worker // 961*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSub 962*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecSADAccumulate 963*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecDotProd 964*795d594fSAndroid Build Coastguard Worker // 965*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: testSADAndDotProdCombined1(byte[] x, byte[] y)966*795d594fSAndroid Build Coastguard Worker public static final int testSADAndDotProdCombined1(byte[] x, byte[] y) { 967*795d594fSAndroid Build Coastguard Worker int s0 = 1; 968*795d594fSAndroid Build Coastguard Worker int s1 = 1; 969*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < x.length; i++) { 970*795d594fSAndroid Build Coastguard Worker int temp0 = x[i] - y[i]; 971*795d594fSAndroid Build Coastguard Worker int temp1 = Math.abs(temp0); 972*795d594fSAndroid Build Coastguard Worker int temp2 = x[i] * (byte)(temp0); 973*795d594fSAndroid Build Coastguard Worker 974*795d594fSAndroid Build Coastguard Worker s0 += temp2; 975*795d594fSAndroid Build Coastguard Worker s1 += temp1; 976*795d594fSAndroid Build Coastguard Worker } 977*795d594fSAndroid Build Coastguard Worker return s0 + s1; 978*795d594fSAndroid Build Coastguard Worker } 979*795d594fSAndroid Build Coastguard Worker 980*795d594fSAndroid Build Coastguard Worker // Regression test for the case, where a loop is vectorized in predicated mode, and there is 981*795d594fSAndroid Build Coastguard Worker // a disambiguation scalar loop added. Make sure that the set, which records instructions 982*795d594fSAndroid Build Coastguard Worker // inserted outside of new loops, is not reset until the full vectorization process has 983*795d594fSAndroid Build Coastguard Worker // happened. 984*795d594fSAndroid Build Coastguard Worker // 985*795d594fSAndroid Build Coastguard Worker // Based on void android.util.Spline$MonotoneCubicSpline.<init>(float[], float[]). 986*795d594fSAndroid Build Coastguard Worker // 987*795d594fSAndroid Build Coastguard Worker /// CHECK-START-ARM64: void Main.$noinline$testExternalSetForLoopWithDisambiguation(int[], int[]) loop_optimization (after) 988*795d594fSAndroid Build Coastguard Worker /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 989*795d594fSAndroid Build Coastguard Worker // 990*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Pred:j\d+>> VecPredSetAll loop:none 991*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecReplicateScalar [{{i\d+}},<<Pred>>] loop:none 992*795d594fSAndroid Build Coastguard Worker // 993*795d594fSAndroid Build Coastguard Worker /// CHECK-ELSE: 994*795d594fSAndroid Build Coastguard Worker // 995*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecReplicateScalar loop:none 996*795d594fSAndroid Build Coastguard Worker // 997*795d594fSAndroid Build Coastguard Worker /// CHECK-FI: 998*795d594fSAndroid Build Coastguard Worker // 999*795d594fSAndroid Build Coastguard Worker // Vector loop. 1000*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<VectorLoop:B\d+>> outer_loop:none 1001*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: VecLoad loop:<<VectorLoop>> outer_loop:none 1002*795d594fSAndroid Build Coastguard Worker // 1003*795d594fSAndroid Build Coastguard Worker // Backup scalar loop. 1004*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<ScalarLoop:B\d+>> outer_loop:none 1005*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<ScalarLoop>> outer_loop:none $noinline$testExternalSetForLoopWithDisambiguation(int[] d, int[] m)1006*795d594fSAndroid Build Coastguard Worker public static void $noinline$testExternalSetForLoopWithDisambiguation(int[] d, int[] m) { 1007*795d594fSAndroid Build Coastguard Worker m[0] = d[0]; 1008*795d594fSAndroid Build Coastguard Worker for (int i = 1; i < m.length; i++) { 1009*795d594fSAndroid Build Coastguard Worker m[i] = (d[i - 1] + d[i]) * 53; 1010*795d594fSAndroid Build Coastguard Worker } 1011*795d594fSAndroid Build Coastguard Worker } 1012*795d594fSAndroid Build Coastguard Worker 1013*795d594fSAndroid Build Coastguard Worker public static final int ARRAY_SIZE = 512; 1014*795d594fSAndroid Build Coastguard Worker createAndInitByteArray(int x)1015*795d594fSAndroid Build Coastguard Worker private static byte[] createAndInitByteArray(int x) { 1016*795d594fSAndroid Build Coastguard Worker byte[] a = new byte[ARRAY_SIZE]; 1017*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1018*795d594fSAndroid Build Coastguard Worker a[i] = (byte)((~i) + x); 1019*795d594fSAndroid Build Coastguard Worker } 1020*795d594fSAndroid Build Coastguard Worker return a; 1021*795d594fSAndroid Build Coastguard Worker } 1022*795d594fSAndroid Build Coastguard Worker createAndInitIntArray(int x)1023*795d594fSAndroid Build Coastguard Worker private static int[] createAndInitIntArray(int x) { 1024*795d594fSAndroid Build Coastguard Worker int[] a = new int[ARRAY_SIZE]; 1025*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1026*795d594fSAndroid Build Coastguard Worker a[i] = (~i) + x; 1027*795d594fSAndroid Build Coastguard Worker } 1028*795d594fSAndroid Build Coastguard Worker return a; 1029*795d594fSAndroid Build Coastguard Worker } 1030*795d594fSAndroid Build Coastguard Worker main(String[] args)1031*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 1032*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 1033*795d594fSAndroid Build Coastguard Worker 1034*795d594fSAndroid Build Coastguard Worker expectEquals(10, earlyExitFirst(-1)); 1035*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= 10; i++) { 1036*795d594fSAndroid Build Coastguard Worker expectEquals(i, earlyExitFirst(i)); 1037*795d594fSAndroid Build Coastguard Worker } 1038*795d594fSAndroid Build Coastguard Worker expectEquals(10, earlyExitFirst(11)); 1039*795d594fSAndroid Build Coastguard Worker 1040*795d594fSAndroid Build Coastguard Worker expectEquals(10, earlyExitLast(-1)); 1041*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1042*795d594fSAndroid Build Coastguard Worker expectEquals(i + 1, earlyExitLast(i)); 1043*795d594fSAndroid Build Coastguard Worker } 1044*795d594fSAndroid Build Coastguard Worker expectEquals(10, earlyExitLast(10)); 1045*795d594fSAndroid Build Coastguard Worker expectEquals(10, earlyExitLast(11)); 1046*795d594fSAndroid Build Coastguard Worker 1047*795d594fSAndroid Build Coastguard Worker expectEquals(2, earlyExitNested()); 1048*795d594fSAndroid Build Coastguard Worker 1049*795d594fSAndroid Build Coastguard Worker expectEquals(17, transferNarrowWrap()); 1050*795d594fSAndroid Build Coastguard Worker expectEquals(-45, polynomialShort()); 1051*795d594fSAndroid Build Coastguard Worker expectEquals(-45, polynomialIntFromLong()); 1052*795d594fSAndroid Build Coastguard Worker expectEquals(-45, polynomialInt()); 1053*795d594fSAndroid Build Coastguard Worker 1054*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(0)); 1055*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(1)); 1056*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(2)); 1057*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(1081788608)); 1058*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(-1081788608)); 1059*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(2147483647)); 1060*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoIntDivLastValue(-2147483648)); 1061*795d594fSAndroid Build Coastguard Worker 1062*795d594fSAndroid Build Coastguard Worker expectEquals( 0, geoIntMulLastValue(0)); 1063*795d594fSAndroid Build Coastguard Worker expectEquals( -194211840, geoIntMulLastValue(1)); 1064*795d594fSAndroid Build Coastguard Worker expectEquals( -388423680, geoIntMulLastValue(2)); 1065*795d594fSAndroid Build Coastguard Worker expectEquals(-1041498112, geoIntMulLastValue(1081788608)); 1066*795d594fSAndroid Build Coastguard Worker expectEquals( 1041498112, geoIntMulLastValue(-1081788608)); 1067*795d594fSAndroid Build Coastguard Worker expectEquals( 194211840, geoIntMulLastValue(2147483647)); 1068*795d594fSAndroid Build Coastguard Worker expectEquals( 0, geoIntMulLastValue(-2147483648)); 1069*795d594fSAndroid Build Coastguard Worker 1070*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(0L)); 1071*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(1L)); 1072*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(2L)); 1073*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(1081788608L)); 1074*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(-1081788608L)); 1075*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(2147483647L)); 1076*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(-2147483648L)); 1077*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(9223372036854775807L)); 1078*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue(-9223372036854775808L)); 1079*795d594fSAndroid Build Coastguard Worker 1080*795d594fSAndroid Build Coastguard Worker expectEquals(0L, geoLongDivLastValue()); 1081*795d594fSAndroid Build Coastguard Worker 1082*795d594fSAndroid Build Coastguard Worker expectEquals( 0L, geoLongMulLastValue(0L)); 1083*795d594fSAndroid Build Coastguard Worker expectEquals(-8070450532247928832L, geoLongMulLastValue(1L)); 1084*795d594fSAndroid Build Coastguard Worker expectEquals( 2305843009213693952L, geoLongMulLastValue(2L)); 1085*795d594fSAndroid Build Coastguard Worker expectEquals( 0L, geoLongMulLastValue(1081788608L)); 1086*795d594fSAndroid Build Coastguard Worker expectEquals( 0L, geoLongMulLastValue(-1081788608L)); 1087*795d594fSAndroid Build Coastguard Worker expectEquals( 8070450532247928832L, geoLongMulLastValue(2147483647L)); 1088*795d594fSAndroid Build Coastguard Worker expectEquals( 0L, geoLongMulLastValue(-2147483648L)); 1089*795d594fSAndroid Build Coastguard Worker expectEquals( 8070450532247928832L, geoLongMulLastValue(9223372036854775807L)); 1090*795d594fSAndroid Build Coastguard Worker expectEquals( 0L, geoLongMulLastValue(-9223372036854775808L)); 1091*795d594fSAndroid Build Coastguard Worker 1092*795d594fSAndroid Build Coastguard Worker float[] a = new float[16]; 1093*795d594fSAndroid Build Coastguard Worker narrowingSubscript(a); 1094*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) { 1095*795d594fSAndroid Build Coastguard Worker expectEquals(2.0f, a[i]); 1096*795d594fSAndroid Build Coastguard Worker } 1097*795d594fSAndroid Build Coastguard Worker 1098*795d594fSAndroid Build Coastguard Worker int[] xx = new int[2]; 1099*795d594fSAndroid Build Coastguard Worker int[] yy = new int[469]; 1100*795d594fSAndroid Build Coastguard Worker reduc(xx, yy); 1101*795d594fSAndroid Build Coastguard Worker expectEquals(-469, xx[0]); 1102*795d594fSAndroid Build Coastguard Worker expectEquals(-938, xx[1]); 1103*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 469; i++) { 1104*795d594fSAndroid Build Coastguard Worker expectEquals(2, yy[i]); 1105*795d594fSAndroid Build Coastguard Worker } 1106*795d594fSAndroid Build Coastguard Worker 1107*795d594fSAndroid Build Coastguard Worker char[] aa = new char[23]; 1108*795d594fSAndroid Build Coastguard Worker String bb = "hello world how are you"; 1109*795d594fSAndroid Build Coastguard Worker string2Bytes(aa, bb); 1110*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < aa.length; i++) { 1111*795d594fSAndroid Build Coastguard Worker expectEquals(aa[i], bb.charAt(i)); 1112*795d594fSAndroid Build Coastguard Worker } 1113*795d594fSAndroid Build Coastguard Worker String cc = "\u1010\u2020llo world how are y\u3030\u4040"; 1114*795d594fSAndroid Build Coastguard Worker string2Bytes(aa, cc); 1115*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < aa.length; i++) { 1116*795d594fSAndroid Build Coastguard Worker expectEquals(aa[i], cc.charAt(i)); 1117*795d594fSAndroid Build Coastguard Worker } 1118*795d594fSAndroid Build Coastguard Worker 1119*795d594fSAndroid Build Coastguard Worker short[] s2s = new short[12]; 1120*795d594fSAndroid Build Coastguard Worker $noinline$stringToShorts(s2s, "abcdefghijkl"); 1121*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < s2s.length; ++i) { 1122*795d594fSAndroid Build Coastguard Worker expectEquals((short) "abcdefghijkl".charAt(i), s2s[i]); 1123*795d594fSAndroid Build Coastguard Worker } 1124*795d594fSAndroid Build Coastguard Worker 1125*795d594fSAndroid Build Coastguard Worker envUsesInCond(); 1126*795d594fSAndroid Build Coastguard Worker 1127*795d594fSAndroid Build Coastguard Worker short[] dd = new short[23]; 1128*795d594fSAndroid Build Coastguard Worker oneBoth(dd, aa); 1129*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < aa.length; i++) { 1130*795d594fSAndroid Build Coastguard Worker expectEquals(aa[i], 1); 1131*795d594fSAndroid Build Coastguard Worker expectEquals(dd[i], 1); 1132*795d594fSAndroid Build Coastguard Worker } 1133*795d594fSAndroid Build Coastguard Worker 1134*795d594fSAndroid Build Coastguard Worker xx[0] = 10; 1135*795d594fSAndroid Build Coastguard Worker byte[] bt = new byte[10]; 1136*795d594fSAndroid Build Coastguard Worker arrayInTripCount(xx, bt, 20); 1137*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < bt.length; i++) { 1138*795d594fSAndroid Build Coastguard Worker expectEquals(40, bt[i]); 1139*795d594fSAndroid Build Coastguard Worker } 1140*795d594fSAndroid Build Coastguard Worker 1141*795d594fSAndroid Build Coastguard Worker byte[] b1 = new byte[259]; // few extra iterations 1142*795d594fSAndroid Build Coastguard Worker byte[] b2 = new byte[259]; 1143*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 259; i++) { 1144*795d594fSAndroid Build Coastguard Worker b1[i] = 0; 1145*795d594fSAndroid Build Coastguard Worker b2[i] = (byte) i; 1146*795d594fSAndroid Build Coastguard Worker } 1147*795d594fSAndroid Build Coastguard Worker typeConv(b1, b2); 1148*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 259; i++) { 1149*795d594fSAndroid Build Coastguard Worker expectEquals((byte)(i + 1), b1[i]); 1150*795d594fSAndroid Build Coastguard Worker } 1151*795d594fSAndroid Build Coastguard Worker 1152*795d594fSAndroid Build Coastguard Worker inductionMax(yy); 1153*795d594fSAndroid Build Coastguard Worker 1154*795d594fSAndroid Build Coastguard Worker int[] f = new int[100]; 1155*795d594fSAndroid Build Coastguard Worker f[0] = 11; 1156*795d594fSAndroid Build Coastguard Worker expectEquals(1000, feedsIntoDeopt(f)); 1157*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 1158*795d594fSAndroid Build Coastguard Worker expectEquals(11, f[i]); 1159*795d594fSAndroid Build Coastguard Worker } 1160*795d594fSAndroid Build Coastguard Worker 1161*795d594fSAndroid Build Coastguard Worker expectEquals(0, absCanBeNegative(-3)); 1162*795d594fSAndroid Build Coastguard Worker expectEquals(3, absCanBeNegative(-2)); 1163*795d594fSAndroid Build Coastguard Worker expectEquals(5, absCanBeNegative(-1)); 1164*795d594fSAndroid Build Coastguard Worker expectEquals(6, absCanBeNegative(0)); 1165*795d594fSAndroid Build Coastguard Worker expectEquals(5, absCanBeNegative(1)); 1166*795d594fSAndroid Build Coastguard Worker expectEquals(3, absCanBeNegative(2)); 1167*795d594fSAndroid Build Coastguard Worker expectEquals(0, absCanBeNegative(3)); 1168*795d594fSAndroid Build Coastguard Worker expectEquals(0, absCanBeNegative(Integer.MAX_VALUE)); 1169*795d594fSAndroid Build Coastguard Worker // Abs(min_int) = min_int. 1170*795d594fSAndroid Build Coastguard Worker int verify = 0; 1171*795d594fSAndroid Build Coastguard Worker try { 1172*795d594fSAndroid Build Coastguard Worker absCanBeNegative(Integer.MIN_VALUE); 1173*795d594fSAndroid Build Coastguard Worker verify = 1; 1174*795d594fSAndroid Build Coastguard Worker } catch (ArrayIndexOutOfBoundsException e) { 1175*795d594fSAndroid Build Coastguard Worker verify = 2; 1176*795d594fSAndroid Build Coastguard Worker } 1177*795d594fSAndroid Build Coastguard Worker expectEquals(2, verify); 1178*795d594fSAndroid Build Coastguard Worker 1179*795d594fSAndroid Build Coastguard Worker int[][] x = new int[128][128]; 1180*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 128; i++) { 1181*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 128; j++) { 1182*795d594fSAndroid Build Coastguard Worker x[i][j] = -i - j; 1183*795d594fSAndroid Build Coastguard Worker } 1184*795d594fSAndroid Build Coastguard Worker } 1185*795d594fSAndroid Build Coastguard Worker expectEquals(-2080768, sum(x)); 1186*795d594fSAndroid Build Coastguard Worker 1187*795d594fSAndroid Build Coastguard Worker largeBody(f); 1188*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 1189*795d594fSAndroid Build Coastguard Worker expectEquals(2805, f[i]); 1190*795d594fSAndroid Build Coastguard Worker } 1191*795d594fSAndroid Build Coastguard Worker 1192*795d594fSAndroid Build Coastguard Worker char[] cx = new char[259]; 1193*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 259; i++) { 1194*795d594fSAndroid Build Coastguard Worker cx[i] = (char) (i - 100); 1195*795d594fSAndroid Build Coastguard Worker } 1196*795d594fSAndroid Build Coastguard Worker castAndNarrow(b1, cx); 1197*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 259; i++) { 1198*795d594fSAndroid Build Coastguard Worker expectEquals((byte)((short) cx[i] + 1), b1[i]); 1199*795d594fSAndroid Build Coastguard Worker } 1200*795d594fSAndroid Build Coastguard Worker 1201*795d594fSAndroid Build Coastguard Worker expectEquals(153, doNotMoveSIMD()); 1202*795d594fSAndroid Build Coastguard Worker 1203*795d594fSAndroid Build Coastguard Worker // This test exposed SIMDization issues on x86 and x86_64 1204*795d594fSAndroid Build Coastguard Worker // so we make sure the test runs with JIT enabled. 1205*795d594fSAndroid Build Coastguard Worker ensureJitCompiled(Main.class, "reduction32Values"); 1206*795d594fSAndroid Build Coastguard Worker { 1207*795d594fSAndroid Build Coastguard Worker int[] a1 = new int[100]; 1208*795d594fSAndroid Build Coastguard Worker int[] a2 = new int[100]; 1209*795d594fSAndroid Build Coastguard Worker int[] a3 = new int[100]; 1210*795d594fSAndroid Build Coastguard Worker int[] a4 = new int[100]; 1211*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 1212*795d594fSAndroid Build Coastguard Worker a1[i] = i; 1213*795d594fSAndroid Build Coastguard Worker a2[i] = 1; 1214*795d594fSAndroid Build Coastguard Worker a3[i] = 100 - i; 1215*795d594fSAndroid Build Coastguard Worker a4[i] = i % 16; 1216*795d594fSAndroid Build Coastguard Worker } 1217*795d594fSAndroid Build Coastguard Worker expectEquals(85800, reduction32Values(a1, a2, a3, a4)); 1218*795d594fSAndroid Build Coastguard Worker } 1219*795d594fSAndroid Build Coastguard Worker { 1220*795d594fSAndroid Build Coastguard Worker float[] a1 = new float[100]; 1221*795d594fSAndroid Build Coastguard Worker float[] a2 = new float[100]; 1222*795d594fSAndroid Build Coastguard Worker float[] a3 = new float[100]; 1223*795d594fSAndroid Build Coastguard Worker float[] a4 = new float[100]; 1224*795d594fSAndroid Build Coastguard Worker int[] a5 = new int[100]; 1225*795d594fSAndroid Build Coastguard Worker 1226*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 1227*795d594fSAndroid Build Coastguard Worker a1[i] = (float)i; 1228*795d594fSAndroid Build Coastguard Worker a2[i] = (float)1; 1229*795d594fSAndroid Build Coastguard Worker a3[i] = (float)(100 - i); 1230*795d594fSAndroid Build Coastguard Worker a4[i] = (i % 16); 1231*795d594fSAndroid Build Coastguard Worker } 1232*795d594fSAndroid Build Coastguard Worker expectEquals(86608.0f, $noinline$ensureSlowPathFPSpillFill(a1, a2, a3, a4, a5)); 1233*795d594fSAndroid Build Coastguard Worker } 1234*795d594fSAndroid Build Coastguard Worker 1235*795d594fSAndroid Build Coastguard Worker expectEquals(10, reductionIntoReplication()); 1236*795d594fSAndroid Build Coastguard Worker 1237*795d594fSAndroid Build Coastguard Worker { 1238*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1239*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1240*795d594fSAndroid Build Coastguard Worker byte[] b_c = createAndInitByteArray(3); 1241*795d594fSAndroid Build Coastguard Worker expectEquals(2731008, testDotProdAndSet(b_a, b_b, b_c)); 1242*795d594fSAndroid Build Coastguard Worker } 1243*795d594fSAndroid Build Coastguard Worker { 1244*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1245*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1246*795d594fSAndroid Build Coastguard Worker expectEquals(5462018, testDotProdAndDotProd(b_a, b_b)); 1247*795d594fSAndroid Build Coastguard Worker } 1248*795d594fSAndroid Build Coastguard Worker { 1249*795d594fSAndroid Build Coastguard Worker int[] i_a = createAndInitIntArray(1); 1250*795d594fSAndroid Build Coastguard Worker int[] i_b = createAndInitIntArray(2); 1251*795d594fSAndroid Build Coastguard Worker int[] i_c = createAndInitIntArray(3); 1252*795d594fSAndroid Build Coastguard Worker expectEquals(512, testSADAndSet(i_a, i_b, i_c)); 1253*795d594fSAndroid Build Coastguard Worker } 1254*795d594fSAndroid Build Coastguard Worker { 1255*795d594fSAndroid Build Coastguard Worker int[] i_a = createAndInitIntArray(1); 1256*795d594fSAndroid Build Coastguard Worker int[] i_b = createAndInitIntArray(2); 1257*795d594fSAndroid Build Coastguard Worker expectEquals(1026, testSADAndSAD(i_a, i_b)); 1258*795d594fSAndroid Build Coastguard Worker } 1259*795d594fSAndroid Build Coastguard Worker { 1260*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1261*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1262*795d594fSAndroid Build Coastguard Worker expectEquals(2731266, testDotProdAndDotProdExtraMul0(b_a, b_b)); 1263*795d594fSAndroid Build Coastguard Worker } 1264*795d594fSAndroid Build Coastguard Worker { 1265*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1266*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1267*795d594fSAndroid Build Coastguard Worker expectEquals(2731266, testDotProdAndDotProdExtraMul1(b_a, b_b)); 1268*795d594fSAndroid Build Coastguard Worker } 1269*795d594fSAndroid Build Coastguard Worker { 1270*795d594fSAndroid Build Coastguard Worker int[] i_a = createAndInitIntArray(1); 1271*795d594fSAndroid Build Coastguard Worker int[] i_b = createAndInitIntArray(2); 1272*795d594fSAndroid Build Coastguard Worker expectEquals(131330, testSADAndSADExtraAbs0(i_a, i_b)); 1273*795d594fSAndroid Build Coastguard Worker } 1274*795d594fSAndroid Build Coastguard Worker { 1275*795d594fSAndroid Build Coastguard Worker int[] i_a = createAndInitIntArray(1); 1276*795d594fSAndroid Build Coastguard Worker int[] i_b = createAndInitIntArray(2); 1277*795d594fSAndroid Build Coastguard Worker expectEquals(131330, testSADAndSADExtraAbs1(i_a, i_b)); 1278*795d594fSAndroid Build Coastguard Worker } 1279*795d594fSAndroid Build Coastguard Worker { 1280*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1281*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1282*795d594fSAndroid Build Coastguard Worker expectEquals(1278, testSADAndDotProdCombined0(b_a, b_b)); 1283*795d594fSAndroid Build Coastguard Worker } 1284*795d594fSAndroid Build Coastguard Worker { 1285*795d594fSAndroid Build Coastguard Worker byte[] b_a = createAndInitByteArray(1); 1286*795d594fSAndroid Build Coastguard Worker byte[] b_b = createAndInitByteArray(2); 1287*795d594fSAndroid Build Coastguard Worker expectEquals(1278, testSADAndDotProdCombined1(b_a, b_b)); 1288*795d594fSAndroid Build Coastguard Worker } 1289*795d594fSAndroid Build Coastguard Worker { 1290*795d594fSAndroid Build Coastguard Worker int[] i_a = createAndInitIntArray(1); 1291*795d594fSAndroid Build Coastguard Worker int[] i_b = createAndInitIntArray(2); 1292*795d594fSAndroid Build Coastguard Worker $noinline$testExternalSetForLoopWithDisambiguation(i_a, i_b); 1293*795d594fSAndroid Build Coastguard Worker 1294*795d594fSAndroid Build Coastguard Worker int sum = 0; 1295*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < i_b.length; i++) { 1296*795d594fSAndroid Build Coastguard Worker sum += i_b[i]; 1297*795d594fSAndroid Build Coastguard Worker } 1298*795d594fSAndroid Build Coastguard Worker expectEquals(-13839413, sum); 1299*795d594fSAndroid Build Coastguard Worker } 1300*795d594fSAndroid Build Coastguard Worker 1301*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 1302*795d594fSAndroid Build Coastguard Worker } 1303*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)1304*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 1305*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1306*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1307*795d594fSAndroid Build Coastguard Worker } 1308*795d594fSAndroid Build Coastguard Worker } 1309*795d594fSAndroid Build Coastguard Worker expectEquals(long expected, long result)1310*795d594fSAndroid Build Coastguard Worker private static void expectEquals(long expected, long result) { 1311*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1312*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1313*795d594fSAndroid Build Coastguard Worker } 1314*795d594fSAndroid Build Coastguard Worker } 1315*795d594fSAndroid Build Coastguard Worker expectEquals(float expected, float result)1316*795d594fSAndroid Build Coastguard Worker private static void expectEquals(float expected, float result) { 1317*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1318*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1319*795d594fSAndroid Build Coastguard Worker } 1320*795d594fSAndroid Build Coastguard Worker } 1321*795d594fSAndroid Build Coastguard Worker } 1322