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 * Tests on loop optimizations related to induction. 19*795d594fSAndroid Build Coastguard Worker */ 20*795d594fSAndroid Build Coastguard Worker public class Main { 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker static int[] a = new int[10]; 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker static int[] novec = new int[20]; // to prevent vectorization 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSingleLoop() loop_optimization (before) 27*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 28*795d594fSAndroid Build Coastguard Worker // 29*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSingleLoop() loop_optimization (after) 30*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadSingleLoop()31*795d594fSAndroid Build Coastguard Worker static void deadSingleLoop() { 32*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 33*795d594fSAndroid Build Coastguard Worker } 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSingleLoop() loop_optimization (before) 37*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 38*795d594fSAndroid Build Coastguard Worker // 39*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSingleLoop() loop_optimization (after) 40*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadSingleLoopN(int n)41*795d594fSAndroid Build Coastguard Worker static void deadSingleLoopN(int n) { 42*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.potentialInfiniteLoop(int) loop_optimization (before) 47*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 48*795d594fSAndroid Build Coastguard Worker // 49*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.potentialInfiniteLoop(int) loop_optimization (after) 50*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none potentialInfiniteLoop(int n)51*795d594fSAndroid Build Coastguard Worker static void potentialInfiniteLoop(int n) { 52*795d594fSAndroid Build Coastguard Worker for (int i = 0; i <= n; i++) { // loops forever when n = MAX_INT 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker } 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadNestedLoops() loop_optimization (before) 57*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 58*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop>> 59*795d594fSAndroid Build Coastguard Worker // 60*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadNestedLoops() loop_optimization (after) 61*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadNestedLoops()62*795d594fSAndroid Build Coastguard Worker static void deadNestedLoops() { 63*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 64*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 4; j++) { 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (before) 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 71*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 72*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>> 73*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>> 74*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 75*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop3>> 76*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 77*795d594fSAndroid Build Coastguard Worker // 78*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (after) 79*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadNestedAndFollowingLoops()80*795d594fSAndroid Build Coastguard Worker static void deadNestedAndFollowingLoops() { 81*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 82*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 4; j++) { 83*795d594fSAndroid Build Coastguard Worker for (int k = 0; k < 4; k++) { 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker for (int k = 0; k < 4; k++) { 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker } 88*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 4; j++) { 89*795d594fSAndroid Build Coastguard Worker for (int k = 0; k < 4; k++) { 90*795d594fSAndroid Build Coastguard Worker } 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) { 94*795d594fSAndroid Build Coastguard Worker } 95*795d594fSAndroid Build Coastguard Worker } 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadConditional(int) loop_optimization (before) 98*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none 99*795d594fSAndroid Build Coastguard Worker // 100*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadConditional(int) loop_optimization (after) 101*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadConditional(int n)102*795d594fSAndroid Build Coastguard Worker public static void deadConditional(int n) { 103*795d594fSAndroid Build Coastguard Worker int k = 0; 104*795d594fSAndroid Build Coastguard Worker int m = 0; 105*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 106*795d594fSAndroid Build Coastguard Worker if (i == 3) 107*795d594fSAndroid Build Coastguard Worker k = i; 108*795d594fSAndroid Build Coastguard Worker else 109*795d594fSAndroid Build Coastguard Worker m = i; 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker } 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadConditionalCycle(int) loop_optimization (before) 114*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 115*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 116*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 117*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 118*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 119*795d594fSAndroid Build Coastguard Worker // 120*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadConditionalCycle(int) loop_optimization (after) 121*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi deadConditionalCycle(int n)122*795d594fSAndroid Build Coastguard Worker public static void deadConditionalCycle(int n) { 123*795d594fSAndroid Build Coastguard Worker int k = 0; 124*795d594fSAndroid Build Coastguard Worker int m = 0; 125*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 126*795d594fSAndroid Build Coastguard Worker if (i == 3) 127*795d594fSAndroid Build Coastguard Worker k--; 128*795d594fSAndroid Build Coastguard Worker else 129*795d594fSAndroid Build Coastguard Worker m++; 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker } 132*795d594fSAndroid Build Coastguard Worker 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadInduction() loop_optimization (before) 135*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 136*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 137*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 138*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 139*795d594fSAndroid Build Coastguard Worker // 140*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadInduction() loop_optimization (after) 141*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 142*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none 143*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 144*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none deadInduction()145*795d594fSAndroid Build Coastguard Worker static void deadInduction() { 146*795d594fSAndroid Build Coastguard Worker int dead = 0; 147*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 148*795d594fSAndroid Build Coastguard Worker a[i] = novec[2 * i] + 1; 149*795d594fSAndroid Build Coastguard Worker dead += 5; 150*795d594fSAndroid Build Coastguard Worker } 151*795d594fSAndroid Build Coastguard Worker } 152*795d594fSAndroid Build Coastguard Worker 153*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadManyInduction() loop_optimization (before) 154*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 155*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 156*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 157*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 158*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 159*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 160*795d594fSAndroid Build Coastguard Worker // 161*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadManyInduction() loop_optimization (after) 162*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 163*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none 164*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 165*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none deadManyInduction()166*795d594fSAndroid Build Coastguard Worker static void deadManyInduction() { 167*795d594fSAndroid Build Coastguard Worker int dead1 = 0, dead2 = 1, dead3 = 3; 168*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 169*795d594fSAndroid Build Coastguard Worker dead1 += 5; 170*795d594fSAndroid Build Coastguard Worker a[i] = novec[2 * i] + 2; 171*795d594fSAndroid Build Coastguard Worker dead2 += 10; 172*795d594fSAndroid Build Coastguard Worker dead3 += 100; 173*795d594fSAndroid Build Coastguard Worker } 174*795d594fSAndroid Build Coastguard Worker } 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSequence() loop_optimization (before) 177*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 178*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 179*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 180*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 181*795d594fSAndroid Build Coastguard Worker // 182*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadSequence() loop_optimization (after) 183*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 184*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none 185*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 186*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none deadSequence()187*795d594fSAndroid Build Coastguard Worker static void deadSequence() { 188*795d594fSAndroid Build Coastguard Worker int dead = 0; 189*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 190*795d594fSAndroid Build Coastguard Worker a[i] = novec[2 * i] + 3; 191*795d594fSAndroid Build Coastguard Worker // Increment value defined inside loop, 192*795d594fSAndroid Build Coastguard Worker // but sequence itself not used anywhere. 193*795d594fSAndroid Build Coastguard Worker dead += i; 194*795d594fSAndroid Build Coastguard Worker } 195*795d594fSAndroid Build Coastguard Worker } 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (before) 198*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 199*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 200*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 201*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 202*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 203*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: BoundsCheck 204*795d594fSAndroid Build Coastguard Worker // 205*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (after) 206*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 207*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none 208*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 209*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 210*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none deadCycleWithException(int k)211*795d594fSAndroid Build Coastguard Worker static void deadCycleWithException(int k) { 212*795d594fSAndroid Build Coastguard Worker int dead = 0; 213*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 214*795d594fSAndroid Build Coastguard Worker a[i] = novec[2 * i] + 4; 215*795d594fSAndroid Build Coastguard Worker // Increment value of dead cycle may throw exception. Dynamic 216*795d594fSAndroid Build Coastguard Worker // BCE takes care of the bounds check though, which enables 217*795d594fSAndroid Build Coastguard Worker // removing the ArrayGet after removing the dead cycle. 218*795d594fSAndroid Build Coastguard Worker dead += a[k]; 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (before) 223*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 224*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 225*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 226*795d594fSAndroid Build Coastguard Worker // 227*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (after) 228*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 229*795d594fSAndroid Build Coastguard Worker // 230*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUp() instruction_simplifier$before_codegen (after) 231*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 12395 loop:none 232*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedFormInductionUp()233*795d594fSAndroid Build Coastguard Worker static int closedFormInductionUp() { 234*795d594fSAndroid Build Coastguard Worker int closed = 12345; 235*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 236*795d594fSAndroid Build Coastguard Worker closed += 5; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker return closed; // only needs last value 239*795d594fSAndroid Build Coastguard Worker } 240*795d594fSAndroid Build Coastguard Worker 241*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (before) 242*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 243*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 244*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 245*795d594fSAndroid Build Coastguard Worker // 246*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (after) 247*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 248*795d594fSAndroid Build Coastguard Worker // 249*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDown(int) instruction_simplifier$before_codegen (after) 250*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 251*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant -50 loop:none 252*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none 253*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Add>>] loop:none closedFormInductionInAndDown(int closed)254*795d594fSAndroid Build Coastguard Worker static int closedFormInductionInAndDown(int closed) { 255*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 256*795d594fSAndroid Build Coastguard Worker closed -= 5; 257*795d594fSAndroid Build Coastguard Worker } 258*795d594fSAndroid Build Coastguard Worker return closed; // only needs last value 259*795d594fSAndroid Build Coastguard Worker } 260*795d594fSAndroid Build Coastguard Worker 261*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (before) 262*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 263*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 264*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Select loop:<<Loop>> outer_loop:none 265*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 266*795d594fSAndroid Build Coastguard Worker // 267*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (after) 268*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 269*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Select 270*795d594fSAndroid Build Coastguard Worker // 271*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionTrivialIf() instruction_simplifier$before_codegen (after) 272*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 81 loop:none 273*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedFormInductionTrivialIf()274*795d594fSAndroid Build Coastguard Worker static int closedFormInductionTrivialIf() { 275*795d594fSAndroid Build Coastguard Worker int closed = 11; 276*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 277*795d594fSAndroid Build Coastguard Worker // Trivial if becomes trivial select at HIR level. 278*795d594fSAndroid Build Coastguard Worker // Make sure this is still recognized as induction. 279*795d594fSAndroid Build Coastguard Worker if (i < 5) { 280*795d594fSAndroid Build Coastguard Worker closed += 7; 281*795d594fSAndroid Build Coastguard Worker } else { 282*795d594fSAndroid Build Coastguard Worker closed += 7; 283*795d594fSAndroid Build Coastguard Worker } 284*795d594fSAndroid Build Coastguard Worker } 285*795d594fSAndroid Build Coastguard Worker return closed; // only needs last value 286*795d594fSAndroid Build Coastguard Worker } 287*795d594fSAndroid Build Coastguard Worker 288*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNested() loop_optimization (before) 289*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none 290*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none 291*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 292*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>> 293*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 294*795d594fSAndroid Build Coastguard Worker // 295*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNested() loop_optimization (after) 296*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 297*795d594fSAndroid Build Coastguard Worker // 298*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNested() instruction_simplifier$before_codegen (after) 299*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 100 loop:none 300*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedFormNested()301*795d594fSAndroid Build Coastguard Worker static int closedFormNested() { 302*795d594fSAndroid Build Coastguard Worker int closed = 0; 303*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 304*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 10; j++) { 305*795d594fSAndroid Build Coastguard Worker closed++; 306*795d594fSAndroid Build Coastguard Worker } 307*795d594fSAndroid Build Coastguard Worker } 308*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 309*795d594fSAndroid Build Coastguard Worker } 310*795d594fSAndroid Build Coastguard Worker 311*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (before) 312*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none 313*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none 314*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 315*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>> 316*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 317*795d594fSAndroid Build Coastguard Worker // 318*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (after) 319*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 320*795d594fSAndroid Build Coastguard Worker // 321*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedAlt() instruction_simplifier$before_codegen (after) 322*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 15082 loop:none 323*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedFormNestedAlt()324*795d594fSAndroid Build Coastguard Worker static int closedFormNestedAlt() { 325*795d594fSAndroid Build Coastguard Worker int closed = 12345; 326*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 17; i++) { 327*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 23; j++) { 328*795d594fSAndroid Build Coastguard Worker closed += 7; 329*795d594fSAndroid Build Coastguard Worker } 330*795d594fSAndroid Build Coastguard Worker } 331*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 332*795d594fSAndroid Build Coastguard Worker } 333*795d594fSAndroid Build Coastguard Worker 334*795d594fSAndroid Build Coastguard Worker // closedFormInductionUpN turns into `if n < 0 then 12345 else 12345 + n * 5`. 335*795d594fSAndroid Build Coastguard Worker 336*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (before) 337*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 338*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 339*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 340*795d594fSAndroid Build Coastguard Worker // 341*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (after) 342*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 343*795d594fSAndroid Build Coastguard Worker // 344*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (after) 345*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 346*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int5:i\d+>> IntConstant 5 347*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int12345:i\d+>> IntConstant 12345 348*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 349*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Int5>>,<<N>>] 350*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Int12345>>] 351*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 352*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Int12345>>,<<Add>>,<<LT>>] 353*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Sel>>] closedFormInductionUpN(int n)354*795d594fSAndroid Build Coastguard Worker static int closedFormInductionUpN(int n) { 355*795d594fSAndroid Build Coastguard Worker int closed = 12345; 356*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 357*795d594fSAndroid Build Coastguard Worker closed += 5; 358*795d594fSAndroid Build Coastguard Worker } 359*795d594fSAndroid Build Coastguard Worker return closed; // only needs last value 360*795d594fSAndroid Build Coastguard Worker } 361*795d594fSAndroid Build Coastguard Worker 362*795d594fSAndroid Build Coastguard Worker // closedFormInductionInAndDownN turns into `if n < 0 then closed else closed - n * 5`. 363*795d594fSAndroid Build Coastguard Worker 364*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (before) 365*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 366*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 367*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 368*795d594fSAndroid Build Coastguard Worker // 369*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (after) 370*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 371*795d594fSAndroid Build Coastguard Worker // 372*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (after) 373*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Closed:i\d+>> ParameterValue 374*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 375*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<IntNeg5:i\d+>> IntConstant -5 376*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 377*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<IntNeg5>>,<<N>>] 378*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Closed>>] 379*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 380*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Closed>>,<<Add>>,<<LT>>] 381*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Sel>>] closedFormInductionInAndDownN(int closed, int n)382*795d594fSAndroid Build Coastguard Worker static int closedFormInductionInAndDownN(int closed, int n) { 383*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 384*795d594fSAndroid Build Coastguard Worker closed -= 5; 385*795d594fSAndroid Build Coastguard Worker } 386*795d594fSAndroid Build Coastguard Worker return closed; // only needs last value 387*795d594fSAndroid Build Coastguard Worker } 388*795d594fSAndroid Build Coastguard Worker 389*795d594fSAndroid Build Coastguard Worker // closedFormNestedN turns into `if (n < 0) then 0 else n * 10` 390*795d594fSAndroid Build Coastguard Worker 391*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (before) 392*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 393*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 394*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 395*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 396*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 397*795d594fSAndroid Build Coastguard Worker // 398*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (after) 399*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 400*795d594fSAndroid Build Coastguard Worker // 401*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (after) 402*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 403*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int10:i\d+>> IntConstant 10 404*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 405*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Int10>>,<<N>>] 406*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Int0>>] 407*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 408*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Int0>>,<<Add>>,<<LT>>] 409*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Sel>>] closedFormNestedN(int n)410*795d594fSAndroid Build Coastguard Worker static int closedFormNestedN(int n) { 411*795d594fSAndroid Build Coastguard Worker int closed = 0; 412*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 413*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 10; j++) { 414*795d594fSAndroid Build Coastguard Worker closed++; 415*795d594fSAndroid Build Coastguard Worker } 416*795d594fSAndroid Build Coastguard Worker } 417*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 418*795d594fSAndroid Build Coastguard Worker } 419*795d594fSAndroid Build Coastguard Worker 420*795d594fSAndroid Build Coastguard Worker // closedFormNestedNAlt turns into `if (n < 0) then 12345 else 12345 + n * 161` 421*795d594fSAndroid Build Coastguard Worker 422*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (before) 423*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 424*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 425*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 426*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 427*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 428*795d594fSAndroid Build Coastguard Worker // 429*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (after) 430*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 431*795d594fSAndroid Build Coastguard Worker // 432*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (after) 433*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 434*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int161:i\d+>> IntConstant 161 435*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int12345:i\d+>> IntConstant 12345 436*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 437*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Int161>>,<<N>>] 438*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Int12345>>] 439*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 440*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Int12345>>,<<Add>>,<<LT>>] 441*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Sel>>] closedFormNestedNAlt(int n)442*795d594fSAndroid Build Coastguard Worker static int closedFormNestedNAlt(int n) { 443*795d594fSAndroid Build Coastguard Worker int closed = 12345; 444*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 445*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 23; j++) { 446*795d594fSAndroid Build Coastguard Worker closed += 7; 447*795d594fSAndroid Build Coastguard Worker } 448*795d594fSAndroid Build Coastguard Worker } 449*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 450*795d594fSAndroid Build Coastguard Worker } 451*795d594fSAndroid Build Coastguard Worker 452*795d594fSAndroid Build Coastguard Worker // We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n`. 453*795d594fSAndroid Build Coastguard Worker // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) 454*795d594fSAndroid Build Coastguard Worker // then 0 else m * n`. 455*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (before) 456*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 457*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 458*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 459*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 460*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 461*795d594fSAndroid Build Coastguard Worker // 462*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) 463*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 464*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 465*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 466*795d594fSAndroid Build Coastguard Worker // 467*795d594fSAndroid Build Coastguard Worker // Inner loop optimization 468*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) 469*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<M:i\d+>> ParameterValue 470*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 471*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 472*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi 473*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<N>>,<<Phi>>] 474*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 475*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Phi>>,<<Add>>,<<LT>>] closedFormNestedMN(int m, int n)476*795d594fSAndroid Build Coastguard Worker static int closedFormNestedMN(int m, int n) { 477*795d594fSAndroid Build Coastguard Worker int closed = 0; 478*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < m; i++) { 479*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < n; j++) { 480*795d594fSAndroid Build Coastguard Worker closed++; 481*795d594fSAndroid Build Coastguard Worker } 482*795d594fSAndroid Build Coastguard Worker } 483*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 484*795d594fSAndroid Build Coastguard Worker } 485*795d594fSAndroid Build Coastguard Worker 486*795d594fSAndroid Build Coastguard Worker // We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n * 7`. 487*795d594fSAndroid Build Coastguard Worker // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) 488*795d594fSAndroid Build Coastguard Worker // then 1245 else 12345 + m * n * 7`. 489*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (before) 490*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 491*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 492*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 493*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 494*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 495*795d594fSAndroid Build Coastguard Worker // 496*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) 497*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 498*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 499*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 500*795d594fSAndroid Build Coastguard Worker // 501*795d594fSAndroid Build Coastguard Worker // Inner loop optimization 502*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) 503*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<M:i\d+>> ParameterValue 504*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<N:i\d+>> ParameterValue 505*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int7:i\d+>> IntConstant 7 506*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 507*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi 508*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Int7>>,<<N>>] 509*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Phi>>] 510*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] 511*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Sel:i\d+>> Select [<<Phi>>,<<Add>>,<<LT>>] closedFormNestedMNAlt(int m, int n)512*795d594fSAndroid Build Coastguard Worker static int closedFormNestedMNAlt(int m, int n) { 513*795d594fSAndroid Build Coastguard Worker int closed = 12345; 514*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < m; i++) { 515*795d594fSAndroid Build Coastguard Worker // if n < 0 then closed else closed + n * 7 516*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < n; j++) { 517*795d594fSAndroid Build Coastguard Worker closed += 7; 518*795d594fSAndroid Build Coastguard Worker } 519*795d594fSAndroid Build Coastguard Worker } 520*795d594fSAndroid Build Coastguard Worker return closed; // only needs last-value 521*795d594fSAndroid Build Coastguard Worker } 522*795d594fSAndroid Build Coastguard Worker 523*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturned() loop_optimization (before) 524*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:{{B\d+}} outer_loop:none 525*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi>>] loop:none 526*795d594fSAndroid Build Coastguard Worker // 527*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturned() loop_optimization (after) 528*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 529*795d594fSAndroid Build Coastguard Worker // 530*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturned() instruction_simplifier$before_codegen (after) 531*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none 532*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none mainIndexReturned()533*795d594fSAndroid Build Coastguard Worker static int mainIndexReturned() { 534*795d594fSAndroid Build Coastguard Worker int i; 535*795d594fSAndroid Build Coastguard Worker for (i = 0; i < 10; i++); 536*795d594fSAndroid Build Coastguard Worker return i; 537*795d594fSAndroid Build Coastguard Worker } 538*795d594fSAndroid Build Coastguard Worker 539*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned9() loop_optimization (before) 540*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 541*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 542*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 543*795d594fSAndroid Build Coastguard Worker // 544*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned9() loop_optimization (after) 545*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 546*795d594fSAndroid Build Coastguard Worker // 547*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned9() instruction_simplifier$before_codegen (after) 548*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 1 loop:none 549*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none periodicReturned9()550*795d594fSAndroid Build Coastguard Worker static int periodicReturned9() { 551*795d594fSAndroid Build Coastguard Worker int k = 0; 552*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 9; i++) { 553*795d594fSAndroid Build Coastguard Worker k = 1 - k; 554*795d594fSAndroid Build Coastguard Worker } 555*795d594fSAndroid Build Coastguard Worker return k; 556*795d594fSAndroid Build Coastguard Worker } 557*795d594fSAndroid Build Coastguard Worker 558*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned10() loop_optimization (before) 559*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 560*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 561*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 562*795d594fSAndroid Build Coastguard Worker // 563*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned10() loop_optimization (after) 564*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 565*795d594fSAndroid Build Coastguard Worker // 566*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturned10() instruction_simplifier$before_codegen (after) 567*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none 568*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none periodicReturned10()569*795d594fSAndroid Build Coastguard Worker static int periodicReturned10() { 570*795d594fSAndroid Build Coastguard Worker int k = 0; 571*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 572*795d594fSAndroid Build Coastguard Worker k = 1 - k; 573*795d594fSAndroid Build Coastguard Worker } 574*795d594fSAndroid Build Coastguard Worker return k; 575*795d594fSAndroid Build Coastguard Worker } 576*795d594fSAndroid Build Coastguard Worker 577*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.getSum21() loop_optimization (before) 578*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 579*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 580*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop>> outer_loop:none 581*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 582*795d594fSAndroid Build Coastguard Worker // 583*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.getSum21() loop_optimization (after) 584*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 585*795d594fSAndroid Build Coastguard Worker // 586*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.getSum21() instruction_simplifier$before_codegen (after) 587*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 21 loop:none 588*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none getSum21()589*795d594fSAndroid Build Coastguard Worker private static int getSum21() { 590*795d594fSAndroid Build Coastguard Worker int k = 0; 591*795d594fSAndroid Build Coastguard Worker int sum = 0; 592*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 6; i++) { 593*795d594fSAndroid Build Coastguard Worker k++; 594*795d594fSAndroid Build Coastguard Worker sum += k; 595*795d594fSAndroid Build Coastguard Worker } 596*795d594fSAndroid Build Coastguard Worker return sum; 597*795d594fSAndroid Build Coastguard Worker } 598*795d594fSAndroid Build Coastguard Worker 599*795d594fSAndroid Build Coastguard Worker // Ensure double induction does not "overshoot" the subscript range. getIncr2(int[] arr)600*795d594fSAndroid Build Coastguard Worker private static int getIncr2(int[] arr) { 601*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 12; ) { 602*795d594fSAndroid Build Coastguard Worker arr[i++] = 30; 603*795d594fSAndroid Build Coastguard Worker arr[i++] = 29; 604*795d594fSAndroid Build Coastguard Worker } 605*795d594fSAndroid Build Coastguard Worker int sum = 0; 606*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 12; i++) { 607*795d594fSAndroid Build Coastguard Worker sum += arr[i]; 608*795d594fSAndroid Build Coastguard Worker } 609*795d594fSAndroid Build Coastguard Worker return sum; 610*795d594fSAndroid Build Coastguard Worker } 611*795d594fSAndroid Build Coastguard Worker 612*795d594fSAndroid Build Coastguard Worker // We can generate a select, which then DCE detects it is redundant. Therefore, we eliminate 613*795d594fSAndroid Build Coastguard Worker // these loops. 614*795d594fSAndroid Build Coastguard Worker 615*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (before) 616*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 617*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 618*795d594fSAndroid Build Coastguard Worker // 619*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) 620*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 621*795d594fSAndroid Build Coastguard Worker // 622*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) 623*795d594fSAndroid Build Coastguard Worker /// CHECK: Select mainIndexReturnedN(int n)624*795d594fSAndroid Build Coastguard Worker static int mainIndexReturnedN(int n) { 625*795d594fSAndroid Build Coastguard Worker int i; 626*795d594fSAndroid Build Coastguard Worker for (i = 0; i < n; i++); 627*795d594fSAndroid Build Coastguard Worker return i; 628*795d594fSAndroid Build Coastguard Worker } 629*795d594fSAndroid Build Coastguard Worker 630*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (before) 631*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 632*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 633*795d594fSAndroid Build Coastguard Worker // 634*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) 635*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 636*795d594fSAndroid Build Coastguard Worker // 637*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) 638*795d594fSAndroid Build Coastguard Worker /// CHECK: Select mainIndexShort1(short s)639*795d594fSAndroid Build Coastguard Worker static int mainIndexShort1(short s) { 640*795d594fSAndroid Build Coastguard Worker int i = 0; 641*795d594fSAndroid Build Coastguard Worker for (i = 0; i < s; i++) { } 642*795d594fSAndroid Build Coastguard Worker return i; 643*795d594fSAndroid Build Coastguard Worker } 644*795d594fSAndroid Build Coastguard Worker 645*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (before) 646*795d594fSAndroid Build Coastguard Worker /// CHECK: Phi 647*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 648*795d594fSAndroid Build Coastguard Worker // 649*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) 650*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 651*795d594fSAndroid Build Coastguard Worker // 652*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) 653*795d594fSAndroid Build Coastguard Worker /// CHECK: Select mainIndexShort2(short s)654*795d594fSAndroid Build Coastguard Worker static int mainIndexShort2(short s) { 655*795d594fSAndroid Build Coastguard Worker int i = 0; 656*795d594fSAndroid Build Coastguard Worker for (i = 0; s > i; i++) { } 657*795d594fSAndroid Build Coastguard Worker return i; 658*795d594fSAndroid Build Coastguard Worker } 659*795d594fSAndroid Build Coastguard Worker 660*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before) 661*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 662*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 663*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 664*795d594fSAndroid Build Coastguard Worker // 665*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (after) 666*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi periodicReturnedN(int n)667*795d594fSAndroid Build Coastguard Worker static int periodicReturnedN(int n) { 668*795d594fSAndroid Build Coastguard Worker int k = 0; 669*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 670*795d594fSAndroid Build Coastguard Worker k = 1 - k; 671*795d594fSAndroid Build Coastguard Worker } 672*795d594fSAndroid Build Coastguard Worker return k; 673*795d594fSAndroid Build Coastguard Worker } 674*795d594fSAndroid Build Coastguard Worker 675*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicOverflowTripCountNotOptimized() loop_optimization (before) 676*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 677*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none 678*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 679*795d594fSAndroid Build Coastguard Worker // 680*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicOverflowTripCountNotOptimized() loop_optimization (after) 681*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 682*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none 683*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none periodicOverflowTripCountNotOptimized()684*795d594fSAndroid Build Coastguard Worker static int periodicOverflowTripCountNotOptimized() { 685*795d594fSAndroid Build Coastguard Worker int k = 0; 686*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE - 81; i += 80) { 687*795d594fSAndroid Build Coastguard Worker k = 1 - k; 688*795d594fSAndroid Build Coastguard Worker } 689*795d594fSAndroid Build Coastguard Worker return k; 690*795d594fSAndroid Build Coastguard Worker } 691*795d594fSAndroid Build Coastguard Worker 692*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicCouldOverflowTripCountNotOptimized(int) loop_optimization (before) 693*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 694*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none 695*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 696*795d594fSAndroid Build Coastguard Worker // 697*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.periodicCouldOverflowTripCountNotOptimized(int) loop_optimization (after) 698*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 699*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none 700*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none periodicCouldOverflowTripCountNotOptimized(int start)701*795d594fSAndroid Build Coastguard Worker static int periodicCouldOverflowTripCountNotOptimized(int start) { 702*795d594fSAndroid Build Coastguard Worker int k = 0; 703*795d594fSAndroid Build Coastguard Worker for (int i = start; i < Integer.MAX_VALUE - 81; i += 80) { 704*795d594fSAndroid Build Coastguard Worker k = 1 - k; 705*795d594fSAndroid Build Coastguard Worker } 706*795d594fSAndroid Build Coastguard Worker return k; 707*795d594fSAndroid Build Coastguard Worker } 708*795d594fSAndroid Build Coastguard Worker 709*795d594fSAndroid Build Coastguard Worker // If ever replaced by closed form, last value should be correct! getSumN(int n)710*795d594fSAndroid Build Coastguard Worker private static int getSumN(int n) { 711*795d594fSAndroid Build Coastguard Worker int k = 0; 712*795d594fSAndroid Build Coastguard Worker int sum = 0; 713*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 714*795d594fSAndroid Build Coastguard Worker k++; 715*795d594fSAndroid Build Coastguard Worker sum += k; 716*795d594fSAndroid Build Coastguard Worker } 717*795d594fSAndroid Build Coastguard Worker return sum; 718*795d594fSAndroid Build Coastguard Worker } 719*795d594fSAndroid Build Coastguard Worker 720*795d594fSAndroid Build Coastguard Worker // If ever replaced by closed form, last value should be correct! closedTwice()721*795d594fSAndroid Build Coastguard Worker private static int closedTwice() { 722*795d594fSAndroid Build Coastguard Worker int closed = 0; 723*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 724*795d594fSAndroid Build Coastguard Worker closed++; 725*795d594fSAndroid Build Coastguard Worker } 726*795d594fSAndroid Build Coastguard Worker // Closed form of first loop defines trip count of second loop. 727*795d594fSAndroid Build Coastguard Worker int other_closed = 0; 728*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < closed; i++) { 729*795d594fSAndroid Build Coastguard Worker other_closed++; 730*795d594fSAndroid Build Coastguard Worker } 731*795d594fSAndroid Build Coastguard Worker return other_closed; 732*795d594fSAndroid Build Coastguard Worker } 733*795d594fSAndroid Build Coastguard Worker 734*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFeed() loop_optimization (before) 735*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none 736*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none 737*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none 738*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none 739*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi3>>] loop:none 740*795d594fSAndroid Build Coastguard Worker /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 741*795d594fSAndroid Build Coastguard Worker // 742*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFeed() loop_optimization (after) 743*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 744*795d594fSAndroid Build Coastguard Worker // 745*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedFeed() instruction_simplifier$before_codegen (after) 746*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 20 loop:none 747*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedFeed()748*795d594fSAndroid Build Coastguard Worker private static int closedFeed() { 749*795d594fSAndroid Build Coastguard Worker int closed = 0; 750*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 751*795d594fSAndroid Build Coastguard Worker closed++; 752*795d594fSAndroid Build Coastguard Worker } 753*795d594fSAndroid Build Coastguard Worker // Closed form of first loop feeds into initial value of second loop, 754*795d594fSAndroid Build Coastguard Worker // used when generating closed form for the latter. 755*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 756*795d594fSAndroid Build Coastguard Worker closed++; 757*795d594fSAndroid Build Coastguard Worker } 758*795d594fSAndroid Build Coastguard Worker return closed; 759*795d594fSAndroid Build Coastguard Worker } 760*795d594fSAndroid Build Coastguard Worker 761*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeUp() loop_optimization (before) 762*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 763*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 764*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 765*795d594fSAndroid Build Coastguard Worker // 766*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeUp() loop_optimization (after) 767*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 768*795d594fSAndroid Build Coastguard Worker // 769*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeUp() instruction_simplifier$before_codegen (after) 770*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant -10 loop:none 771*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedLargeUp()772*795d594fSAndroid Build Coastguard Worker private static int closedLargeUp() { 773*795d594fSAndroid Build Coastguard Worker int closed = 0; 774*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 775*795d594fSAndroid Build Coastguard Worker closed += 0x7fffffff; 776*795d594fSAndroid Build Coastguard Worker } 777*795d594fSAndroid Build Coastguard Worker return closed; 778*795d594fSAndroid Build Coastguard Worker } 779*795d594fSAndroid Build Coastguard Worker 780*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeDown() loop_optimization (before) 781*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 782*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 783*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 784*795d594fSAndroid Build Coastguard Worker // 785*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeDown() loop_optimization (after) 786*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 787*795d594fSAndroid Build Coastguard Worker // 788*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLargeDown() instruction_simplifier$before_codegen (after) 789*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none 790*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedLargeDown()791*795d594fSAndroid Build Coastguard Worker private static int closedLargeDown() { 792*795d594fSAndroid Build Coastguard Worker int closed = 0; 793*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 794*795d594fSAndroid Build Coastguard Worker closed -= 0x7fffffff; 795*795d594fSAndroid Build Coastguard Worker } 796*795d594fSAndroid Build Coastguard Worker return closed; 797*795d594fSAndroid Build Coastguard Worker } 798*795d594fSAndroid Build Coastguard Worker 799*795d594fSAndroid Build Coastguard Worker // Checks that we do not loop optimize if the calculation of the trip count would overflow. 800*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLinearStepOverflow() loop_optimization (before) 801*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 802*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 803*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 804*795d594fSAndroid Build Coastguard Worker // 805*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedLinearStepOverflow() loop_optimization (after) 806*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 807*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 808*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none closedLinearStepOverflow()809*795d594fSAndroid Build Coastguard Worker private static int closedLinearStepOverflow() { 810*795d594fSAndroid Build Coastguard Worker int closed = 0; 811*795d594fSAndroid Build Coastguard Worker // Note that this isn't a "one-off" error. 812*795d594fSAndroid Build Coastguard Worker // We are using MIN and MAX to make sure we overflow. 813*795d594fSAndroid Build Coastguard Worker for (int i = Integer.MIN_VALUE; i < (Integer.MAX_VALUE - 80); i += 79) { 814*795d594fSAndroid Build Coastguard Worker closed++; 815*795d594fSAndroid Build Coastguard Worker } 816*795d594fSAndroid Build Coastguard Worker return closed; 817*795d594fSAndroid Build Coastguard Worker } 818*795d594fSAndroid Build Coastguard Worker 819*795d594fSAndroid Build Coastguard Worker // Since we cannot guarantee that the start/end wouldn't overflow we do not perform loop 820*795d594fSAndroid Build Coastguard Worker // optimization. 821*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$inline$closedByParameters(int, int) loop_optimization (before) 822*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 823*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 824*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 825*795d594fSAndroid Build Coastguard Worker // 826*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$inline$closedByParameters(int, int) loop_optimization (after) 827*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 828*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 829*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none $inline$closedByParameters(int start, int end)830*795d594fSAndroid Build Coastguard Worker private static int $inline$closedByParameters(int start, int end) { 831*795d594fSAndroid Build Coastguard Worker int closed = 0; 832*795d594fSAndroid Build Coastguard Worker for (int i = start; i < end; i++) { 833*795d594fSAndroid Build Coastguard Worker closed++; 834*795d594fSAndroid Build Coastguard Worker } 835*795d594fSAndroid Build Coastguard Worker return closed; 836*795d594fSAndroid Build Coastguard Worker } 837*795d594fSAndroid Build Coastguard Worker 838*795d594fSAndroid Build Coastguard Worker // Since we are inlining `closedByParameters` we know that the parameters are fixed and 839*795d594fSAndroid Build Coastguard Worker // therefore we can perform loop optimization. 840*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedByParametersWithInline() loop_optimization (before) 841*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 842*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 843*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 844*795d594fSAndroid Build Coastguard Worker // 845*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedByParametersWithInline() loop_optimization (after) 846*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 847*795d594fSAndroid Build Coastguard Worker // 848*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.closedByParametersWithInline() instruction_simplifier$before_codegen (after) 849*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none 850*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none closedByParametersWithInline()851*795d594fSAndroid Build Coastguard Worker private static int closedByParametersWithInline() { 852*795d594fSAndroid Build Coastguard Worker return $inline$closedByParameters(0, 10); 853*795d594fSAndroid Build Coastguard Worker } 854*795d594fSAndroid Build Coastguard Worker 855*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.waterFall() loop_optimization (before) 856*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none 857*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none 858*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none 859*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none 860*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none 861*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi5>>] loop:none 862*795d594fSAndroid Build Coastguard Worker // 863*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.waterFall() loop_optimization (after) 864*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 865*795d594fSAndroid Build Coastguard Worker // 866*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.waterFall() instruction_simplifier$before_codegen (after) 867*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 50 loop:none 868*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none waterFall()869*795d594fSAndroid Build Coastguard Worker private static int waterFall() { 870*795d594fSAndroid Build Coastguard Worker int i = 0; 871*795d594fSAndroid Build Coastguard Worker for (; i < 10; i++); 872*795d594fSAndroid Build Coastguard Worker for (; i < 20; i++); 873*795d594fSAndroid Build Coastguard Worker for (; i < 30; i++); 874*795d594fSAndroid Build Coastguard Worker for (; i < 40; i++); 875*795d594fSAndroid Build Coastguard Worker for (; i < 50; i++); 876*795d594fSAndroid Build Coastguard Worker return i; // this should become just 50 877*795d594fSAndroid Build Coastguard Worker } 878*795d594fSAndroid Build Coastguard Worker 879*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (before) 880*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 881*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 882*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 883*795d594fSAndroid Build Coastguard Worker // 884*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom1() loop_optimization (after) 885*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 886*795d594fSAndroid Build Coastguard Worker // 887*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom1() instruction_simplifier$before_codegen (after) 888*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none 889*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none periodicBoolIdiom1()890*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom1() { 891*795d594fSAndroid Build Coastguard Worker boolean x = true; 892*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 7; i++) { 893*795d594fSAndroid Build Coastguard Worker x = !x; 894*795d594fSAndroid Build Coastguard Worker } 895*795d594fSAndroid Build Coastguard Worker return x; 896*795d594fSAndroid Build Coastguard Worker } 897*795d594fSAndroid Build Coastguard Worker 898*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (before) 899*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 900*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 901*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 902*795d594fSAndroid Build Coastguard Worker // 903*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom2() loop_optimization (after) 904*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 905*795d594fSAndroid Build Coastguard Worker // 906*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom2() instruction_simplifier$before_codegen (after) 907*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none 908*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none periodicBoolIdiom2()909*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom2() { 910*795d594fSAndroid Build Coastguard Worker boolean x = true; 911*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 7; i++) { 912*795d594fSAndroid Build Coastguard Worker x = (x != true); 913*795d594fSAndroid Build Coastguard Worker } 914*795d594fSAndroid Build Coastguard Worker return x; 915*795d594fSAndroid Build Coastguard Worker } 916*795d594fSAndroid Build Coastguard Worker 917*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (before) 918*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 919*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 920*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi1>>] loop:none 921*795d594fSAndroid Build Coastguard Worker // 922*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom3() loop_optimization (after) 923*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 924*795d594fSAndroid Build Coastguard Worker // 925*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom3() instruction_simplifier$before_codegen (after) 926*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none 927*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Int>>] loop:none periodicBoolIdiom3()928*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom3() { 929*795d594fSAndroid Build Coastguard Worker boolean x = true; 930*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 7; i++) { 931*795d594fSAndroid Build Coastguard Worker x = (x == false); 932*795d594fSAndroid Build Coastguard Worker } 933*795d594fSAndroid Build Coastguard Worker return x; 934*795d594fSAndroid Build Coastguard Worker } 935*795d594fSAndroid Build Coastguard Worker 936*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (before) 937*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 938*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 939*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 940*795d594fSAndroid Build Coastguard Worker // 941*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom1N(boolean, int) loop_optimization (after) 942*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi periodicBoolIdiom1N(boolean x, int n)943*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom1N(boolean x, int n) { 944*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 945*795d594fSAndroid Build Coastguard Worker x = !x; 946*795d594fSAndroid Build Coastguard Worker } 947*795d594fSAndroid Build Coastguard Worker return x; 948*795d594fSAndroid Build Coastguard Worker } 949*795d594fSAndroid Build Coastguard Worker 950*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (before) 951*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 952*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 953*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 954*795d594fSAndroid Build Coastguard Worker // 955*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom2N(boolean, int) loop_optimization (after) 956*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi periodicBoolIdiom2N(boolean x, int n)957*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom2N(boolean x, int n) { 958*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 959*795d594fSAndroid Build Coastguard Worker x = (x != true); 960*795d594fSAndroid Build Coastguard Worker } 961*795d594fSAndroid Build Coastguard Worker return x; 962*795d594fSAndroid Build Coastguard Worker } 963*795d594fSAndroid Build Coastguard Worker 964*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (before) 965*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 966*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none 967*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 968*795d594fSAndroid Build Coastguard Worker // 969*795d594fSAndroid Build Coastguard Worker /// CHECK-START: boolean Main.periodicBoolIdiom3N(boolean, int) loop_optimization (after) 970*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi periodicBoolIdiom3N(boolean x, int n)971*795d594fSAndroid Build Coastguard Worker private static boolean periodicBoolIdiom3N(boolean x, int n) { 972*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 973*795d594fSAndroid Build Coastguard Worker x = (x == false); 974*795d594fSAndroid Build Coastguard Worker } 975*795d594fSAndroid Build Coastguard Worker return x; 976*795d594fSAndroid Build Coastguard Worker } 977*795d594fSAndroid Build Coastguard Worker 978*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat10() loop_optimization (before) 979*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 980*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none 981*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none 982*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none 983*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 984*795d594fSAndroid Build Coastguard Worker // 985*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat10() loop_optimization (after) 986*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 987*795d594fSAndroid Build Coastguard Worker // 988*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat10() loop_optimization (after) 989*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Float:f\d+>> FloatConstant 2 loop:none 990*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Float>>] loop:none periodicFloat10()991*795d594fSAndroid Build Coastguard Worker private static float periodicFloat10() { 992*795d594fSAndroid Build Coastguard Worker float r = 4.5f; 993*795d594fSAndroid Build Coastguard Worker float s = 2.0f; 994*795d594fSAndroid Build Coastguard Worker float t = -1.0f; 995*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 996*795d594fSAndroid Build Coastguard Worker float tmp = t; 997*795d594fSAndroid Build Coastguard Worker t = r; 998*795d594fSAndroid Build Coastguard Worker r = s; 999*795d594fSAndroid Build Coastguard Worker s = tmp; 1000*795d594fSAndroid Build Coastguard Worker } 1001*795d594fSAndroid Build Coastguard Worker return r; 1002*795d594fSAndroid Build Coastguard Worker } 1003*795d594fSAndroid Build Coastguard Worker 1004*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat11() loop_optimization (before) 1005*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 1006*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none 1007*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none 1008*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none 1009*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 1010*795d594fSAndroid Build Coastguard Worker // 1011*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat11() loop_optimization (after) 1012*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 1013*795d594fSAndroid Build Coastguard Worker // 1014*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat11() loop_optimization (after) 1015*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Float:f\d+>> FloatConstant -1 loop:none 1016*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Float>>] loop:none periodicFloat11()1017*795d594fSAndroid Build Coastguard Worker private static float periodicFloat11() { 1018*795d594fSAndroid Build Coastguard Worker float r = 4.5f; 1019*795d594fSAndroid Build Coastguard Worker float s = 2.0f; 1020*795d594fSAndroid Build Coastguard Worker float t = -1.0f; 1021*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 11; i++) { 1022*795d594fSAndroid Build Coastguard Worker float tmp = t; 1023*795d594fSAndroid Build Coastguard Worker t = r; 1024*795d594fSAndroid Build Coastguard Worker r = s; 1025*795d594fSAndroid Build Coastguard Worker s = tmp; 1026*795d594fSAndroid Build Coastguard Worker } 1027*795d594fSAndroid Build Coastguard Worker return r; 1028*795d594fSAndroid Build Coastguard Worker } 1029*795d594fSAndroid Build Coastguard Worker 1030*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat12() loop_optimization (before) 1031*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 1032*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:f\d+>> Phi loop:<<Loop>> outer_loop:none 1033*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi3:f\d+>> Phi loop:<<Loop>> outer_loop:none 1034*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi4:f\d+>> Phi loop:<<Loop>> outer_loop:none 1035*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Phi2>>] loop:none 1036*795d594fSAndroid Build Coastguard Worker // 1037*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat12() loop_optimization (after) 1038*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi 1039*795d594fSAndroid Build Coastguard Worker // 1040*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.periodicFloat12() loop_optimization (after) 1041*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Float:f\d+>> FloatConstant 4.5 loop:none 1042*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Float>>] loop:none periodicFloat12()1043*795d594fSAndroid Build Coastguard Worker private static float periodicFloat12() { 1044*795d594fSAndroid Build Coastguard Worker float r = 4.5f; 1045*795d594fSAndroid Build Coastguard Worker float s = 2.0f; 1046*795d594fSAndroid Build Coastguard Worker float t = -1.0f; 1047*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 12; i++) { 1048*795d594fSAndroid Build Coastguard Worker float tmp = t; 1049*795d594fSAndroid Build Coastguard Worker t = r; 1050*795d594fSAndroid Build Coastguard Worker r = s; 1051*795d594fSAndroid Build Coastguard Worker s = tmp; 1052*795d594fSAndroid Build Coastguard Worker } 1053*795d594fSAndroid Build Coastguard Worker return r; 1054*795d594fSAndroid Build Coastguard Worker } 1055*795d594fSAndroid Build Coastguard Worker exceptionExitBeforeAdd()1056*795d594fSAndroid Build Coastguard Worker private static int exceptionExitBeforeAdd() { 1057*795d594fSAndroid Build Coastguard Worker int k = 0; 1058*795d594fSAndroid Build Coastguard Worker try { 1059*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1060*795d594fSAndroid Build Coastguard Worker a[i] = 0; 1061*795d594fSAndroid Build Coastguard Worker k += 10; // increment last 1062*795d594fSAndroid Build Coastguard Worker } 1063*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 1064*795d594fSAndroid Build Coastguard Worker // Flag error by returning current 1065*795d594fSAndroid Build Coastguard Worker // value of k negated. 1066*795d594fSAndroid Build Coastguard Worker return -k - 1; 1067*795d594fSAndroid Build Coastguard Worker } 1068*795d594fSAndroid Build Coastguard Worker return k; 1069*795d594fSAndroid Build Coastguard Worker } 1070*795d594fSAndroid Build Coastguard Worker exceptionExitAfterAdd()1071*795d594fSAndroid Build Coastguard Worker private static int exceptionExitAfterAdd() { 1072*795d594fSAndroid Build Coastguard Worker int k = 0; 1073*795d594fSAndroid Build Coastguard Worker try { 1074*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 1075*795d594fSAndroid Build Coastguard Worker k += 10; // increment first 1076*795d594fSAndroid Build Coastguard Worker a[i] = 0; 1077*795d594fSAndroid Build Coastguard Worker } 1078*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 1079*795d594fSAndroid Build Coastguard Worker // Flag error by returning current 1080*795d594fSAndroid Build Coastguard Worker // value of k negated. 1081*795d594fSAndroid Build Coastguard Worker return -k - 1; 1082*795d594fSAndroid Build Coastguard Worker } 1083*795d594fSAndroid Build Coastguard Worker return k; 1084*795d594fSAndroid Build Coastguard Worker } 1085*795d594fSAndroid Build Coastguard Worker 1086*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.closedLinearInductionUnmatchedTypesNotOptimized() loop_optimization (before) 1087*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 1088*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:j\d+>> Phi loop:<<Loop>> outer_loop:none 1089*795d594fSAndroid Build Coastguard Worker // 1090*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.closedLinearInductionUnmatchedTypesNotOptimized() loop_optimization (after) 1091*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 1092*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi2:j\d+>> Phi loop:<<Loop>> outer_loop:none closedLinearInductionUnmatchedTypesNotOptimized()1093*795d594fSAndroid Build Coastguard Worker private static long closedLinearInductionUnmatchedTypesNotOptimized() { 1094*795d594fSAndroid Build Coastguard Worker long sum = 0; 1095*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; ++i) { 1096*795d594fSAndroid Build Coastguard Worker ++sum; 1097*795d594fSAndroid Build Coastguard Worker } 1098*795d594fSAndroid Build Coastguard Worker return sum; 1099*795d594fSAndroid Build Coastguard Worker } 1100*795d594fSAndroid Build Coastguard Worker 1101*795d594fSAndroid Build Coastguard Worker /// CHECK-START: short Main.closedLinearInductionNarrowingNotOptimized() loop_optimization (before) 1102*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 1103*795d594fSAndroid Build Coastguard Worker // 1104*795d594fSAndroid Build Coastguard Worker /// CHECK-START: short Main.closedLinearInductionNarrowingNotOptimized() loop_optimization (after) 1105*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none closedLinearInductionNarrowingNotOptimized()1106*795d594fSAndroid Build Coastguard Worker private static short closedLinearInductionNarrowingNotOptimized() { 1107*795d594fSAndroid Build Coastguard Worker short i = 0; 1108*795d594fSAndroid Build Coastguard Worker for (; i < 10; ++i); 1109*795d594fSAndroid Build Coastguard Worker return i; 1110*795d594fSAndroid Build Coastguard Worker } 1111*795d594fSAndroid Build Coastguard Worker main(String[] args)1112*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 1113*795d594fSAndroid Build Coastguard Worker deadSingleLoop(); 1114*795d594fSAndroid Build Coastguard Worker deadSingleLoopN(4); 1115*795d594fSAndroid Build Coastguard Worker potentialInfiniteLoop(4); 1116*795d594fSAndroid Build Coastguard Worker deadNestedLoops(); 1117*795d594fSAndroid Build Coastguard Worker deadNestedAndFollowingLoops(); 1118*795d594fSAndroid Build Coastguard Worker deadConditional(4); 1119*795d594fSAndroid Build Coastguard Worker deadConditionalCycle(4); 1120*795d594fSAndroid Build Coastguard Worker 1121*795d594fSAndroid Build Coastguard Worker deadInduction(); 1122*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1123*795d594fSAndroid Build Coastguard Worker expectEquals(1, a[i]); 1124*795d594fSAndroid Build Coastguard Worker } 1125*795d594fSAndroid Build Coastguard Worker deadManyInduction(); 1126*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1127*795d594fSAndroid Build Coastguard Worker expectEquals(2, a[i]); 1128*795d594fSAndroid Build Coastguard Worker } 1129*795d594fSAndroid Build Coastguard Worker deadSequence(); 1130*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1131*795d594fSAndroid Build Coastguard Worker expectEquals(3, a[i]); 1132*795d594fSAndroid Build Coastguard Worker } 1133*795d594fSAndroid Build Coastguard Worker try { 1134*795d594fSAndroid Build Coastguard Worker deadCycleWithException(-1); 1135*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: IOOB exception"); 1136*795d594fSAndroid Build Coastguard Worker } catch (IndexOutOfBoundsException e) { 1137*795d594fSAndroid Build Coastguard Worker } 1138*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1139*795d594fSAndroid Build Coastguard Worker expectEquals(i == 0 ? 4 : 3, a[i]); 1140*795d594fSAndroid Build Coastguard Worker } 1141*795d594fSAndroid Build Coastguard Worker deadCycleWithException(0); 1142*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < a.length; i++) { 1143*795d594fSAndroid Build Coastguard Worker expectEquals(4, a[i]); 1144*795d594fSAndroid Build Coastguard Worker } 1145*795d594fSAndroid Build Coastguard Worker 1146*795d594fSAndroid Build Coastguard Worker expectEquals(12395, closedFormInductionUp()); 1147*795d594fSAndroid Build Coastguard Worker expectEquals(12295, closedFormInductionInAndDown(12345)); 1148*795d594fSAndroid Build Coastguard Worker expectEquals(81, closedFormInductionTrivialIf()); 1149*795d594fSAndroid Build Coastguard Worker expectEquals(10 * 10, closedFormNested()); 1150*795d594fSAndroid Build Coastguard Worker expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt()); 1151*795d594fSAndroid Build Coastguard Worker for (int n = -4; n < 10; n++) { 1152*795d594fSAndroid Build Coastguard Worker int tc = (n <= 0) ? 0 : n; 1153*795d594fSAndroid Build Coastguard Worker expectEquals(12345 + tc * 5, closedFormInductionUpN(n)); 1154*795d594fSAndroid Build Coastguard Worker expectEquals(12345 - tc * 5, closedFormInductionInAndDownN(12345, n)); 1155*795d594fSAndroid Build Coastguard Worker expectEquals(tc * 10, closedFormNestedN(n)); 1156*795d594fSAndroid Build Coastguard Worker expectEquals(12345 + tc * 23 * 7, closedFormNestedNAlt(n)); 1157*795d594fSAndroid Build Coastguard Worker expectEquals(tc * (tc + 1), closedFormNestedMN(n, n + 1)); 1158*795d594fSAndroid Build Coastguard Worker expectEquals(12345 + tc * (tc + 1) * 7, closedFormNestedMNAlt(n, n + 1)); 1159*795d594fSAndroid Build Coastguard Worker } 1160*795d594fSAndroid Build Coastguard Worker 1161*795d594fSAndroid Build Coastguard Worker expectEquals(10, mainIndexReturned()); 1162*795d594fSAndroid Build Coastguard Worker expectEquals(1, periodicReturned9()); 1163*795d594fSAndroid Build Coastguard Worker expectEquals(0, periodicReturned10()); 1164*795d594fSAndroid Build Coastguard Worker expectEquals(21, getSum21()); 1165*795d594fSAndroid Build Coastguard Worker expectEquals(354, getIncr2(new int[12])); 1166*795d594fSAndroid Build Coastguard Worker for (int n = -4; n < 4; n++) { 1167*795d594fSAndroid Build Coastguard Worker int tc = (n <= 0) ? 0 : n; 1168*795d594fSAndroid Build Coastguard Worker expectEquals(tc, mainIndexReturnedN(n)); 1169*795d594fSAndroid Build Coastguard Worker expectEquals(tc, mainIndexShort1((short) n)); 1170*795d594fSAndroid Build Coastguard Worker expectEquals(tc, mainIndexShort2((short) n)); 1171*795d594fSAndroid Build Coastguard Worker expectEquals(tc & 1, periodicReturnedN(n)); 1172*795d594fSAndroid Build Coastguard Worker expectEquals((tc * (tc + 1)) / 2, getSumN(n)); 1173*795d594fSAndroid Build Coastguard Worker } 1174*795d594fSAndroid Build Coastguard Worker 1175*795d594fSAndroid Build Coastguard Worker expectEquals(1, periodicOverflowTripCountNotOptimized()); 1176*795d594fSAndroid Build Coastguard Worker expectEquals(1, periodicCouldOverflowTripCountNotOptimized(Integer.MIN_VALUE)); 1177*795d594fSAndroid Build Coastguard Worker 1178*795d594fSAndroid Build Coastguard Worker expectEquals(10, closedTwice()); 1179*795d594fSAndroid Build Coastguard Worker expectEquals(20, closedFeed()); 1180*795d594fSAndroid Build Coastguard Worker expectEquals(-10, closedLargeUp()); 1181*795d594fSAndroid Build Coastguard Worker expectEquals(10, closedLargeDown()); 1182*795d594fSAndroid Build Coastguard Worker expectEquals(54366674, closedLinearStepOverflow()); 1183*795d594fSAndroid Build Coastguard Worker expectEquals(10, $inline$closedByParameters(0, 10)); 1184*795d594fSAndroid Build Coastguard Worker expectEquals(10, closedByParametersWithInline()); 1185*795d594fSAndroid Build Coastguard Worker expectEquals(50, waterFall()); 1186*795d594fSAndroid Build Coastguard Worker 1187*795d594fSAndroid Build Coastguard Worker expectEquals(false, periodicBoolIdiom1()); 1188*795d594fSAndroid Build Coastguard Worker expectEquals(false, periodicBoolIdiom2()); 1189*795d594fSAndroid Build Coastguard Worker expectEquals(false, periodicBoolIdiom3()); 1190*795d594fSAndroid Build Coastguard Worker for (int n = -4; n < 10; n++) { 1191*795d594fSAndroid Build Coastguard Worker int tc = (n <= 0) ? 0 : n; 1192*795d594fSAndroid Build Coastguard Worker boolean even = (tc & 1) == 0; 1193*795d594fSAndroid Build Coastguard Worker expectEquals(even, periodicBoolIdiom1N(true, n)); 1194*795d594fSAndroid Build Coastguard Worker expectEquals(!even, periodicBoolIdiom1N(false, n)); 1195*795d594fSAndroid Build Coastguard Worker expectEquals(even, periodicBoolIdiom2N(true, n)); 1196*795d594fSAndroid Build Coastguard Worker expectEquals(!even, periodicBoolIdiom2N(false, n)); 1197*795d594fSAndroid Build Coastguard Worker expectEquals(even, periodicBoolIdiom3N(true, n)); 1198*795d594fSAndroid Build Coastguard Worker expectEquals(!even, periodicBoolIdiom3N(false, n)); 1199*795d594fSAndroid Build Coastguard Worker } 1200*795d594fSAndroid Build Coastguard Worker 1201*795d594fSAndroid Build Coastguard Worker expectEquals( 2.0f, periodicFloat10()); 1202*795d594fSAndroid Build Coastguard Worker expectEquals(-1.0f, periodicFloat11()); 1203*795d594fSAndroid Build Coastguard Worker expectEquals( 4.5f, periodicFloat12()); 1204*795d594fSAndroid Build Coastguard Worker 1205*795d594fSAndroid Build Coastguard Worker expectEquals(100, exceptionExitBeforeAdd()); 1206*795d594fSAndroid Build Coastguard Worker expectEquals(100, exceptionExitAfterAdd()); 1207*795d594fSAndroid Build Coastguard Worker a = null; 1208*795d594fSAndroid Build Coastguard Worker expectEquals(-1, exceptionExitBeforeAdd()); 1209*795d594fSAndroid Build Coastguard Worker expectEquals(-11, exceptionExitAfterAdd()); 1210*795d594fSAndroid Build Coastguard Worker a = new int[4]; 1211*795d594fSAndroid Build Coastguard Worker expectEquals(-41, exceptionExitBeforeAdd()); 1212*795d594fSAndroid Build Coastguard Worker expectEquals(-51, exceptionExitAfterAdd()); 1213*795d594fSAndroid Build Coastguard Worker 1214*795d594fSAndroid Build Coastguard Worker expectEquals(10, closedLinearInductionUnmatchedTypesNotOptimized()); 1215*795d594fSAndroid Build Coastguard Worker expectEquals(10, closedLinearInductionNarrowingNotOptimized()); 1216*795d594fSAndroid Build Coastguard Worker 1217*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 1218*795d594fSAndroid Build Coastguard Worker } 1219*795d594fSAndroid Build Coastguard Worker expectEquals(float expected, float result)1220*795d594fSAndroid Build Coastguard Worker private static void expectEquals(float expected, float result) { 1221*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1222*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1223*795d594fSAndroid Build Coastguard Worker } 1224*795d594fSAndroid Build Coastguard Worker } 1225*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)1226*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 1227*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1228*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1229*795d594fSAndroid Build Coastguard Worker } 1230*795d594fSAndroid Build Coastguard Worker } 1231*795d594fSAndroid Build Coastguard Worker expectEquals(boolean expected, boolean result)1232*795d594fSAndroid Build Coastguard Worker private static void expectEquals(boolean expected, boolean result) { 1233*795d594fSAndroid Build Coastguard Worker if (expected != result) { 1234*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 1235*795d594fSAndroid Build Coastguard Worker } 1236*795d594fSAndroid Build Coastguard Worker } 1237*795d594fSAndroid Build Coastguard Worker } 1238