Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * Tests for optimizations of break-loops, i.e. loops that break
     19  * out of a while-true loop when the end condition is satisfied.
     20  * In particular, the tests focus on break-loops that can be
     21  * rewritten into regular countable loops (this may improve certain
     22  * loops generated by the Kotlin compiler for inclusive ranges).
     23  */
     24 public class Main {
     25 
     26   /// CHECK-START: int Main.breakLoop(int[]) induction_var_analysis (before)
     27   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
     28   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
     29   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
     30   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
     31   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
     32   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
     33   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<One>>] loop:<<Loop>>      outer_loop:none
     34   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]        loop:<<Loop>>      outer_loop:none
     35   /// CHECK-DAG:               If [<<NE>>]                        loop:<<Loop>>      outer_loop:none
     36   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
     37   //
     38   /// CHECK-START: int Main.breakLoop(int[]) induction_var_analysis (after)
     39   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
     40   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
     41   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
     42   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
     43   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
     44   /// CHECK-DAG: <<LE:z\d+>>   LessThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
     45   /// CHECK-DAG:               If [<<LE>>]                        loop:<<Loop>>      outer_loop:none
     46   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
     47   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<One>>] loop:<<Loop>>      outer_loop:none
     48   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
     49   //
     50   /// CHECK-START-ARM64: int Main.breakLoop(int[]) loop_optimization (after)
     51   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                          loop:none
     52   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                           loop:none
     53   /// CHECK-DAG: <<Four:i\d+>> IntConstant 4                           loop:none
     54   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                     loop:none
     55   /// CHECK-DAG: <<Rep:d\d+>>  VecReplicateScalar [<<One>>]            loop:none
     56   /// CHECK-DAG:               VecStore [<<Nil>>,<<Phi:i\d+>>,<<Rep>>] loop:<<Loop:B\d+>> outer_loop:none
     57   /// CHECK-DAG:               Add [<<Phi>>,<<Four>>]                  loop:<<Loop>>      outer_loop:none
     58   static int breakLoop(int[] a) {
     59     int l = 0;
     60     int u = a.length - 1;
     61     int i = l;
     62     if (l <= u) {
     63       while (true) {
     64         a[i] = 1;
     65         if (i == u) break;
     66         i++;
     67       }
     68     }
     69     return i;
     70   }
     71 
     72   /// CHECK-START: int Main.breakLoopDown(int[]) induction_var_analysis (before)
     73   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
     74   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
     75   /// CHECK-DAG: <<MOne:i\d+>> IntConstant -1                     loop:none
     76   /// CHECK-DAG: <<Two:i\d+>>  IntConstant 2                      loop:none
     77   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
     78   /// CHECK-DAG: <<Phi:i\d+>>  Phi [{{i\d+}},<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
     79   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
     80   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Two>>] loop:<<Loop>>      outer_loop:none
     81   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [<<Phi>>,<<Zero>>]        loop:<<Loop>>      outer_loop:none
     82   /// CHECK-DAG:               If [<<NE>>]                        loop:<<Loop>>      outer_loop:none
     83   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<MOne>>]             loop:<<Loop>>      outer_loop:none
     84   //
     85   /// CHECK-START: int Main.breakLoopDown(int[]) induction_var_analysis (after)
     86   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                        loop:none
     87   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                         loop:none
     88   /// CHECK-DAG: <<MOne:i\d+>> IntConstant -1                        loop:none
     89   /// CHECK-DAG: <<Two:i\d+>>  IntConstant 2                         loop:none
     90   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                   loop:none
     91   /// CHECK-DAG: <<Phi:i\d+>>  Phi [{{i\d+}},<<AddI:i\d+>>]          loop:<<Loop:B\d+>> outer_loop:none
     92   /// CHECK-DAG: <<GE:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Zero>>] loop:<<Loop>>      outer_loop:none
     93   /// CHECK-DAG:               If [<<GE>>]                           loop:<<Loop>>      outer_loop:none
     94   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]        loop:<<Loop>>      outer_loop:none
     95   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Two>>]    loop:<<Loop>>      outer_loop:none
     96   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<MOne>>]                loop:<<Loop>>      outer_loop:none
     97   static int breakLoopDown(int[] a) {
     98     int l = 0;
     99     int u = a.length - 1;
    100     int i = u;
    101     if (u >= l) {
    102       while (true) {
    103         a[i] = 2;
    104         if (i == l) break;
    105         i--;
    106       }
    107     }
    108     return i;
    109   }
    110 
    111   /// CHECK-START: int Main.breakLoopSafeConst(int[]) induction_var_analysis (before)
    112   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
    113   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
    114   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                        loop:none
    115   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483631               loop:none
    116   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483646               loop:none
    117   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
    118   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
    119   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
    120   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
    121   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Three>>] loop:<<Loop>>      outer_loop:none
    122   /// CHECK-DAG: <<NE:z\d+>>    NotEqual [<<Phi>>,<<L2>>]            loop:<<Loop>>      outer_loop:none
    123   /// CHECK-DAG:                If [<<NE>>]                          loop:<<Loop>>      outer_loop:none
    124   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
    125   //
    126   /// CHECK-START: int Main.breakLoopSafeConst(int[]) induction_var_analysis (after)
    127   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                        loop:none
    128   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
    129   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                        loop:none
    130   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483631               loop:none
    131   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483646               loop:none
    132   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
    133   /// CHECK-DAG: <<LE:z\d+>>    LessThanOrEqual [<<Phi>>,<<L2>>]     loop:<<Loop>>      outer_loop:none
    134   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
    135   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
    136   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
    137   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Three>>] loop:<<Loop>>      outer_loop:none
    138   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
    139   //
    140   /// CHECK-START-ARM64: int Main.breakLoopSafeConst(int[]) loop_optimization (after)
    141   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                          loop:none
    142   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                           loop:none
    143   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                           loop:none
    144   /// CHECK-DAG: <<Four:i\d+>>  IntConstant 4                           loop:none
    145   /// CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Three>>]          loop:none
    146   /// CHECK-DAG:                VecStore [<<Par>>,<<Phi:i\d+>>,<<Rep>>] loop:<<Loop:B\d+>> outer_loop:none
    147   /// CHECK-DAG:                Add [<<Phi>>,<<Four>>]                  loop:<<Loop>>      outer_loop:none
    148   static int breakLoopSafeConst(int[] a) {
    149     int l = Integer.MAX_VALUE - 16;
    150     int u = Integer.MAX_VALUE - 1;
    151     int i = l;
    152     if (l <= u) {  // will be removed by simplifier
    153       while (true) {
    154         a[i - l] = 3;
    155         if (i == u) break;
    156         i++;
    157       }
    158     }
    159     return i;
    160   }
    161 
    162   /// CHECK-START: int Main.breakLoopUnsafeConst(int[]) induction_var_analysis (before)
    163   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
    164   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
    165   /// CHECK-DAG: <<Four:i\d+>>  IntConstant 4                        loop:none
    166   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483632               loop:none
    167   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483647               loop:none
    168   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
    169   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
    170   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
    171   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
    172   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Four>>]  loop:<<Loop>>      outer_loop:none
    173   /// CHECK-DAG: <<NE:z\d+>>    NotEqual [<<Phi>>,<<L2>>]            loop:<<Loop>>      outer_loop:none
    174   /// CHECK-DAG:                If [<<NE>>]                          loop:<<Loop>>      outer_loop:none
    175   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
    176   //
    177   /// CHECK-START: int Main.breakLoopUnsafeConst(int[]) induction_var_analysis (after)
    178   /// CHECK-DAG:                NotEqual
    179   /// CHECK-NOT:                LessThanOrEqual
    180   static int breakLoopUnsafeConst(int[] a) {
    181     int l = Integer.MAX_VALUE - 15;
    182     int u = Integer.MAX_VALUE;
    183     int i = l;
    184     if (l <= u) {  // will be removed by simplifier
    185       while (true) {
    186         a[i - l] = 4;
    187         if (i == u) break;  // rewriting exit not safe!
    188         i++;
    189       }
    190     }
    191     return i;
    192   }
    193 
    194   /// CHECK-START: int Main.breakLoopNastyPhi(int[]) induction_var_analysis (before)
    195   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                      loop:none
    196   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                       loop:none
    197   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                       loop:none
    198   /// CHECK-DAG: <<Five:i\d+>> IntConstant 5                       loop:none
    199   /// CHECK-DAG: <<M123:i\d+>> IntConstant -123                    loop:none
    200   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                 loop:none
    201   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]        loop:<<Loop:B\d+>> outer_loop:none
    202   /// CHECK-DAG: <<Wrap:i\d+>> Phi [<<M123>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
    203   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]      loop:<<Loop>>      outer_loop:none
    204   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Five>>] loop:<<Loop>>      outer_loop:none
    205   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]         loop:<<Loop>>      outer_loop:none
    206   /// CHECK-DAG:               If [<<NE>>]                         loop:<<Loop>>      outer_loop:none
    207   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]               loop:<<Loop>>      outer_loop:none
    208   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<M123>>,<<Wrap>>]             loop:none
    209   /// CHECK-DAG:               Return [<<Comb>>]                   loop:none
    210   //
    211   /// CHECK-START: int Main.breakLoopNastyPhi(int[]) induction_var_analysis (after)
    212   /// CHECK-DAG:               NotEqual
    213   /// CHECK-NOT:               LessThanOrEqual
    214   static int breakLoopNastyPhi(int[] a) {
    215     int l = 0;
    216     int u = a.length - 1;
    217     int x = -123;
    218     if (l <= u) {
    219       int i = l;
    220       while (true) {
    221         a[i] = 5;
    222         if (i == u) break;
    223         x = i;
    224         i++;
    225       }
    226     }
    227     return x;  // keep another phi live
    228   }
    229 
    230   /// CHECK-START: int Main.breakLoopReduction(int[]) induction_var_analysis (before)
    231   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                 loop:none
    232   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                  loop:none
    233   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                  loop:none
    234   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                 loop:none
    235   /// CHECK-DAG: <<Red:i\d+>>  Phi [<<Zero>>,<<RedI:i\d+>>]   loop:<<Loop:B\d+>> outer_loop:none
    236   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]   loop:<<Loop>>      outer_loop:none
    237   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
    238   /// CHECK-DAG: <<Get:i\d+>>  ArrayGet [<<Nil>>,<<Bnd>>]     loop:<<Loop>>      outer_loop:none
    239   /// CHECK-DAG: <<RedI>>      Add [<<Red>>,<<Get>>]          loop:<<Loop>>      outer_loop:none
    240   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]    loop:<<Loop>>      outer_loop:none
    241   /// CHECK-DAG:               If [<<NE>>]                    loop:<<Loop>>      outer_loop:none
    242   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]          loop:<<Loop>>      outer_loop:none
    243   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<Zero>>,<<RedI>>]        loop:none
    244   /// CHECK-DAG:               Return [<<Comb>>]              loop:none
    245   //
    246   /// CHECK-START: int Main.breakLoopReduction(int[]) induction_var_analysis (after)
    247   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
    248   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
    249   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
    250   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
    251   /// CHECK-DAG: <<Red:i\d+>>  Phi [<<Zero>>,<<RedI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
    252   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop>>      outer_loop:none
    253   /// CHECK-DAG: <<LE:z\d+>>   LessThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
    254   /// CHECK-DAG:               If [<<LE>>]                        loop:<<Loop>>      outer_loop:none
    255   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
    256   /// CHECK-DAG: <<Get:i\d+>>  ArrayGet [<<Nil>>,<<Bnd>>]         loop:<<Loop>>      outer_loop:none
    257   /// CHECK-DAG: <<RedI>>      Add [<<Red>>,<<Get>>]              loop:<<Loop>>      outer_loop:none
    258   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
    259   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<Zero>>,<<Red>>]             loop:none
    260   /// CHECK-DAG:               Return [<<Comb>>]                  loop:none
    261   //
    262   /// CHECK-START-ARM64: int Main.breakLoopReduction(int[]) loop_optimization (after)
    263   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue              loop:none
    264   /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0               loop:none
    265   /// CHECK-DAG: <<Exp:d\d+>>   VecSetScalars [<<Zero>>]    loop:none
    266   /// CHECK-DAG: <<VPhi:d\d+>>  Phi [<<Exp>>,<<VAdd:d\d+>>] loop:<<Loop:B\d+>> outer_loop:none
    267   /// CHECK-DAG: <<VLoad:d\d+>> VecLoad                     loop:<<Loop>>      outer_loop:none
    268   /// CHECK-DAG: <<VAdd>>       VecAdd [<<VPhi>>,<<VLoad>>] loop:<<Loop>>      outer_loop:none
    269   static int breakLoopReduction(int[] a) {
    270     int l = 0;
    271     int u = a.length - 1;
    272     int x = 0;
    273     if (l <= u) {
    274       int i = l;
    275       while (true) {
    276         x += a[i];
    277         if (i == u) break;
    278         i++;
    279       }
    280     }
    281     return x;
    282   }
    283 
    284   //
    285   // Test driver.
    286   //
    287 
    288   public static void main(String[] args) {
    289     int[] a = new int[100];
    290 
    291     expectEquals(99, breakLoop(a));
    292     for (int i = 0; i < a.length; i++) {
    293       expectEquals(1, a[i]);
    294     }
    295 
    296     expectEquals(0, breakLoopDown(a));
    297     for (int i = 0; i < a.length; i++) {
    298       expectEquals(2, a[i]);
    299     }
    300 
    301     expectEquals(Integer.MAX_VALUE - 1, breakLoopSafeConst(a));
    302     for (int i = 0; i < a.length; i++) {
    303       int e = i < 16 ? 3 : 2;
    304       expectEquals(e, a[i]);
    305     }
    306 
    307     expectEquals(Integer.MAX_VALUE, breakLoopUnsafeConst(a));
    308     for (int i = 0; i < a.length; i++) {
    309       int e = i < 16 ? 4 : 2;
    310       expectEquals(e, a[i]);
    311     }
    312 
    313     expectEquals(98, breakLoopNastyPhi(a));
    314     for (int i = 0; i < a.length; i++) {
    315       expectEquals(5, a[i]);
    316     }
    317 
    318     expectEquals(500, breakLoopReduction(a));
    319 
    320     System.out.println("passed");
    321   }
    322 
    323   private static void expectEquals(int expected, int result) {
    324     if (expected != result) {
    325       throw new Error("Expected: " + expected + ", found: " + result);
    326     }
    327   }
    328 }
    329