1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker // 18*795d594fSAndroid Build Coastguard Worker // Test on loop optimizations, in particular around geometric induction. 19*795d594fSAndroid Build Coastguard Worker // 20*795d594fSAndroid Build Coastguard Worker public class Main { 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1(int) loop_optimization (before) 23*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 24*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Mul loop:<<Loop>> 25*795d594fSAndroid Build Coastguard Worker // 26*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1(int) loop_optimization (after) 27*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 28*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 29*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none 30*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none 31*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none 32*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Add>>] loop:none 33*795d594fSAndroid Build Coastguard Worker // 34*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1(int) loop_optimization (after) 35*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geo1(int a)36*795d594fSAndroid Build Coastguard Worker public static int geo1(int a) { 37*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 38*795d594fSAndroid Build Coastguard Worker a *= 10; 39*795d594fSAndroid Build Coastguard Worker } 40*795d594fSAndroid Build Coastguard Worker return a; 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2(int) loop_optimization (before) 44*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 45*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Shl loop:<<Loop>> 46*795d594fSAndroid Build Coastguard Worker // 47*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2(int) loop_optimization (after) 48*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 49*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 50*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024 loop:none 51*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none 52*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none 53*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Add>>] loop:none 54*795d594fSAndroid Build Coastguard Worker // 55*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2(int) loop_optimization (after) 56*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geo2(int a)57*795d594fSAndroid Build Coastguard Worker public static int geo2(int a) { 58*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 59*795d594fSAndroid Build Coastguard Worker a <<= 1; 60*795d594fSAndroid Build Coastguard Worker } 61*795d594fSAndroid Build Coastguard Worker return a; 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo3(int) loop_optimization (before) 65*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 66*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Div loop:<<Loop>> 67*795d594fSAndroid Build Coastguard Worker // 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo3(int) loop_optimization (after) 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 71*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049 loop:none 72*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none 73*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none 74*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Add>>] loop:none 75*795d594fSAndroid Build Coastguard Worker // 76*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo3(int) loop_optimization (after) 77*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geo3(int a)78*795d594fSAndroid Build Coastguard Worker public static int geo3(int a) { 79*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 80*795d594fSAndroid Build Coastguard Worker a /= 3; 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker return a; 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo4(int) loop_optimization (before) 86*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 87*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Rem loop:<<Loop>> 88*795d594fSAndroid Build Coastguard Worker // 89*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo4(int) loop_optimization (after) 90*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 91*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 7 loop:none 92*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none 93*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Rem>>] loop:none 94*795d594fSAndroid Build Coastguard Worker // 95*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo4(int) loop_optimization (after) 96*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geo4(int a)97*795d594fSAndroid Build Coastguard Worker public static int geo4(int a) { 98*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 99*795d594fSAndroid Build Coastguard Worker a %= 7; // a wrap-around induction 100*795d594fSAndroid Build Coastguard Worker } 101*795d594fSAndroid Build Coastguard Worker return a; 102*795d594fSAndroid Build Coastguard Worker } 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo5() loop_optimization (before) 105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 106*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Shr loop:<<Loop>> 107*795d594fSAndroid Build Coastguard Worker // 108*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo5() loop_optimization (after) 109*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none 110*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none 111*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none 112*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none 113*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none 114*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Add>>] loop:none 115*795d594fSAndroid Build Coastguard Worker // 116*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo5() loop_optimization (after) 117*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geo5()118*795d594fSAndroid Build Coastguard Worker public static int geo5() { 119*795d594fSAndroid Build Coastguard Worker int a = 0x7fffffff; 120*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 121*795d594fSAndroid Build Coastguard Worker a >>= 1; 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker return a; 124*795d594fSAndroid Build Coastguard Worker } 125*795d594fSAndroid Build Coastguard Worker 126*795d594fSAndroid Build Coastguard Worker // TODO: someday? 127*795d594fSAndroid Build Coastguard Worker // 128*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1BCE() BCE (before) 129*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:none 130*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 131*795d594fSAndroid Build Coastguard Worker // 132*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1BCE() BCE (after) 133*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 134*795d594fSAndroid Build Coastguard Worker // 135*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo1BCE() BCE (after) 136*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:none 137*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize geo1BCE()138*795d594fSAndroid Build Coastguard Worker public static int geo1BCE() { 139*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 140*795d594fSAndroid Build Coastguard Worker 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 141*795d594fSAndroid Build Coastguard Worker 21, 22, 23, 24, 25, 26 }; 142*795d594fSAndroid Build Coastguard Worker int a = 1; 143*795d594fSAndroid Build Coastguard Worker int r = 0; 144*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) { 145*795d594fSAndroid Build Coastguard Worker r += x[a]; 146*795d594fSAndroid Build Coastguard Worker a *= 5; 147*795d594fSAndroid Build Coastguard Worker } 148*795d594fSAndroid Build Coastguard Worker return r; 149*795d594fSAndroid Build Coastguard Worker } 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker // TODO: someday? 152*795d594fSAndroid Build Coastguard Worker // 153*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2BCE() BCE (before) 154*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:none 155*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 156*795d594fSAndroid Build Coastguard Worker // 157*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2BCE() BCE (after) 158*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 159*795d594fSAndroid Build Coastguard Worker // 160*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo2BCE() BCE (after) 161*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck loop:none 162*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize geo2BCE()163*795d594fSAndroid Build Coastguard Worker public static int geo2BCE() { 164*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 165*795d594fSAndroid Build Coastguard Worker 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 166*795d594fSAndroid Build Coastguard Worker 21, 22, 23, 24, 25, 26 }; 167*795d594fSAndroid Build Coastguard Worker int a = 1; 168*795d594fSAndroid Build Coastguard Worker int r = 0; 169*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 5; i++) { 170*795d594fSAndroid Build Coastguard Worker r += x[a]; 171*795d594fSAndroid Build Coastguard Worker a <<= 1; 172*795d594fSAndroid Build Coastguard Worker } 173*795d594fSAndroid Build Coastguard Worker return r; 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo3BCE() BCE (before) 177*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:none 178*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 179*795d594fSAndroid Build Coastguard Worker // 180*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo3BCE() BCE (after) 181*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 182*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize geo3BCE()183*795d594fSAndroid Build Coastguard Worker public static int geo3BCE() { 184*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 185*795d594fSAndroid Build Coastguard Worker 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 186*795d594fSAndroid Build Coastguard Worker 21, 22, 23, 24, 25, 26 }; 187*795d594fSAndroid Build Coastguard Worker int a = 25; 188*795d594fSAndroid Build Coastguard Worker int r = 0; 189*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { // a converges to 0 190*795d594fSAndroid Build Coastguard Worker r += x[a]; 191*795d594fSAndroid Build Coastguard Worker a /= 5; 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker return r; 194*795d594fSAndroid Build Coastguard Worker } 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo4BCE() BCE (before) 197*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:none 198*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: BoundsCheck loop:{{B\d+}} 199*795d594fSAndroid Build Coastguard Worker // 200*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geo4BCE() BCE (after) 201*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 202*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Deoptimize geo4BCE()203*795d594fSAndroid Build Coastguard Worker public static int geo4BCE() { 204*795d594fSAndroid Build Coastguard Worker int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 205*795d594fSAndroid Build Coastguard Worker 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 206*795d594fSAndroid Build Coastguard Worker 21, 22, 23, 24, 25, 26 }; 207*795d594fSAndroid Build Coastguard Worker int a = 25; 208*795d594fSAndroid Build Coastguard Worker int r = 0; 209*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { // a converges to 0 210*795d594fSAndroid Build Coastguard Worker r += x[a]; 211*795d594fSAndroid Build Coastguard Worker a %= 5; // a wrap-around induction 212*795d594fSAndroid Build Coastguard Worker } 213*795d594fSAndroid Build Coastguard Worker return r; 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (before) 217*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 218*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Mul loop:<<Loop>> 219*795d594fSAndroid Build Coastguard Worker // 220*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (after) 221*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 222*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Zero>>] 223*795d594fSAndroid Build Coastguard Worker // 224*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (after) 225*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 226*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Mul geoMulBlackHole(int a)227*795d594fSAndroid Build Coastguard Worker public static int geoMulBlackHole(int a) { 228*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 229*795d594fSAndroid Build Coastguard Worker a *= 10; 230*795d594fSAndroid Build Coastguard Worker } 231*795d594fSAndroid Build Coastguard Worker return a; 232*795d594fSAndroid Build Coastguard Worker } 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (before) 235*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 236*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Shl loop:<<Loop>> 237*795d594fSAndroid Build Coastguard Worker // 238*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (after) 239*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 240*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Zero>>] 241*795d594fSAndroid Build Coastguard Worker // 242*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (after) 243*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 244*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Shl geoShlBlackHole(int a)245*795d594fSAndroid Build Coastguard Worker public static int geoShlBlackHole(int a) { 246*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 247*795d594fSAndroid Build Coastguard Worker a <<= 1; 248*795d594fSAndroid Build Coastguard Worker } 249*795d594fSAndroid Build Coastguard Worker return a; 250*795d594fSAndroid Build Coastguard Worker } 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (before) 253*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 254*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Div loop:<<Loop>> 255*795d594fSAndroid Build Coastguard Worker // 256*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (after) 257*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 258*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Zero>>] 259*795d594fSAndroid Build Coastguard Worker // 260*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (after) 261*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 262*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Div geoDivBlackHole(int a)263*795d594fSAndroid Build Coastguard Worker public static int geoDivBlackHole(int a) { 264*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 265*795d594fSAndroid Build Coastguard Worker a /= 10; 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker return a; 268*795d594fSAndroid Build Coastguard Worker } 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker // Even though Rem is already optimized away by the time induction analysis 271*795d594fSAndroid Build Coastguard Worker // and the loop optimizer run, the loop is optimized with a trivial 272*795d594fSAndroid Build Coastguard Worker // wrap-around induction just as the wrap-around for REM would. 273*795d594fSAndroid Build Coastguard Worker // 274*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (before) 275*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 276*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> 277*795d594fSAndroid Build Coastguard Worker // 278*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (after) 279*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 280*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Zero>>] 281*795d594fSAndroid Build Coastguard Worker // 282*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (after) 283*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi geoRemBlackHole(int a)284*795d594fSAndroid Build Coastguard Worker public static int geoRemBlackHole(int a) { 285*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 100; i++) { 286*795d594fSAndroid Build Coastguard Worker a %= 1; 287*795d594fSAndroid Build Coastguard Worker } 288*795d594fSAndroid Build Coastguard Worker return a; 289*795d594fSAndroid Build Coastguard Worker } 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker // 292*795d594fSAndroid Build Coastguard Worker // Verifier. 293*795d594fSAndroid Build Coastguard Worker // 294*795d594fSAndroid Build Coastguard Worker main(String[] args)295*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 296*795d594fSAndroid Build Coastguard Worker int m = 1410065408; 297*795d594fSAndroid Build Coastguard Worker for (int i = -100; i <= 100; i++) { 298*795d594fSAndroid Build Coastguard Worker expectEquals(m * i, geo1(i)); 299*795d594fSAndroid Build Coastguard Worker } 300*795d594fSAndroid Build Coastguard Worker for (int i = 1; i <= 1000000000; i *= 10) { 301*795d594fSAndroid Build Coastguard Worker expectEquals( m * i, geo1( i)); 302*795d594fSAndroid Build Coastguard Worker expectEquals(-m * i, geo1(-i)); 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker 305*795d594fSAndroid Build Coastguard Worker for (int i = -100; i <= 100; i++) { 306*795d594fSAndroid Build Coastguard Worker expectEquals(i << 10, geo2(i)); 307*795d594fSAndroid Build Coastguard Worker } 308*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 22; i++) { 309*795d594fSAndroid Build Coastguard Worker expectEquals(1 << (i + 10), geo2(1 << i)); 310*795d594fSAndroid Build Coastguard Worker } 311*795d594fSAndroid Build Coastguard Worker expectEquals(0x80000400, geo2(0x00200001)); 312*795d594fSAndroid Build Coastguard Worker expectEquals(0x00000000, geo2(0x00400000)); 313*795d594fSAndroid Build Coastguard Worker expectEquals(0x00000400, geo2(0x00400001)); 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker int d = 59049; 316*795d594fSAndroid Build Coastguard Worker for (int i = -100; i <= 100; i++) { 317*795d594fSAndroid Build Coastguard Worker expectEquals(0, geo3(i)); 318*795d594fSAndroid Build Coastguard Worker } 319*795d594fSAndroid Build Coastguard Worker for (int i = 1; i <= 100; i++) { 320*795d594fSAndroid Build Coastguard Worker expectEquals( i, geo3( i * d)); 321*795d594fSAndroid Build Coastguard Worker expectEquals( i, geo3( i * d + 1)); 322*795d594fSAndroid Build Coastguard Worker expectEquals(-i, geo3(-i * d)); 323*795d594fSAndroid Build Coastguard Worker expectEquals(-i, geo3(-i * d - 1)); 324*795d594fSAndroid Build Coastguard Worker } 325*795d594fSAndroid Build Coastguard Worker 326*795d594fSAndroid Build Coastguard Worker for (int i = -100; i <= 100; i++) { 327*795d594fSAndroid Build Coastguard Worker expectEquals(i % 7, geo4(i)); 328*795d594fSAndroid Build Coastguard Worker } 329*795d594fSAndroid Build Coastguard Worker 330*795d594fSAndroid Build Coastguard Worker expectEquals(0x1fffff, geo5()); 331*795d594fSAndroid Build Coastguard Worker 332*795d594fSAndroid Build Coastguard Worker expectEquals(34, geo1BCE()); 333*795d594fSAndroid Build Coastguard Worker expectEquals(36, geo2BCE()); 334*795d594fSAndroid Build Coastguard Worker expectEquals(131, geo3BCE()); 335*795d594fSAndroid Build Coastguard Worker expectEquals(125, geo4BCE()); 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker // Nothing escapes! 338*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoMulBlackHole(0)); 339*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoShlBlackHole(0)); 340*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoDivBlackHole(0)); 341*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoRemBlackHole(0)); 342*795d594fSAndroid Build Coastguard Worker for (int i = -100; i <= 100; i++) { 343*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoMulBlackHole(i)); 344*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoShlBlackHole(i)); 345*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoDivBlackHole(i)); 346*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoRemBlackHole(i)); 347*795d594fSAndroid Build Coastguard Worker } 348*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 31; i++) { 349*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoMulBlackHole(1 << i)); 350*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoShlBlackHole(1 << i)); 351*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoDivBlackHole(1 << i)); 352*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoRemBlackHole(1 << i)); 353*795d594fSAndroid Build Coastguard Worker } 354*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoMulBlackHole(0x7fffffff)); 355*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoShlBlackHole(0x7fffffff)); 356*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoDivBlackHole(0x7fffffff)); 357*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoRemBlackHole(0x7fffffff)); 358*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoMulBlackHole(0x80000000)); 359*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoShlBlackHole(0x80000000)); 360*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoDivBlackHole(0x80000000)); 361*795d594fSAndroid Build Coastguard Worker expectEquals(0, geoRemBlackHole(0x80000000)); 362*795d594fSAndroid Build Coastguard Worker 363*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 364*795d594fSAndroid Build Coastguard Worker } 365*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)366*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 367*795d594fSAndroid Build Coastguard Worker if (expected != result) { 368*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 369*795d594fSAndroid Build Coastguard Worker } 370*795d594fSAndroid Build Coastguard Worker } 371*795d594fSAndroid Build Coastguard Worker } 372