xref: /aosp_15_r20/art/test/669-checker-break/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 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 for optimizations of break-loops, i.e. loops that break
19*795d594fSAndroid Build Coastguard Worker  * out of a while-true loop when the end condition is satisfied.
20*795d594fSAndroid Build Coastguard Worker  * In particular, the tests focus on break-loops that can be
21*795d594fSAndroid Build Coastguard Worker  * rewritten into regular countable loops (this may improve certain
22*795d594fSAndroid Build Coastguard Worker  * loops generated by the Kotlin compiler for inclusive ranges).
23*795d594fSAndroid Build Coastguard Worker  */
24*795d594fSAndroid Build Coastguard Worker public class Main {
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoop(int[]) induction_var_analysis (before)
27*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
28*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
29*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
30*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
31*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
32*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
33*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<One>>] loop:<<Loop>>      outer_loop:none
34*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]        loop:<<Loop>>      outer_loop:none
35*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<NE>>]                        loop:<<Loop>>      outer_loop:none
36*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
37*795d594fSAndroid Build Coastguard Worker   //
38*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoop(int[]) induction_var_analysis (after)
39*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
40*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
41*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
42*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
43*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
44*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<LE:z\d+>>   LessThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
45*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<LE>>]                        loop:<<Loop>>      outer_loop:none
46*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
47*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<One>>] loop:<<Loop>>      outer_loop:none
48*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
49*795d594fSAndroid Build Coastguard Worker   //
50*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.breakLoop(int[]) loop_optimization (after)
51*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                          loop:none
52*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                           loop:none
53*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                     loop:none
54*795d594fSAndroid Build Coastguard Worker   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
55*795d594fSAndroid Build Coastguard Worker   //
56*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<One>>,{{j\d+}}]             loop:none
57*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile                                      loop:<<Loop:B\d+>> outer_loop:none
58*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                VecStore [<<Nil>>,<<Phi:i\d+>>,<<Rep>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
59*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                            loop:<<Loop>>      outer_loop:none
60*795d594fSAndroid Build Coastguard Worker   //
61*795d594fSAndroid Build Coastguard Worker   /// CHECK-ELSE:
62*795d594fSAndroid Build Coastguard Worker   //
63*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Four:i\d+>>  IntConstant 4                           loop:none
64*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<One>>]            loop:none
65*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                VecStore [<<Nil>>,<<Phi:i\d+>>,<<Rep>>] loop:<<Loop:B\d+>> outer_loop:none
66*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                Add [<<Phi>>,<<Four>>]                  loop:<<Loop>>      outer_loop:none
67*795d594fSAndroid Build Coastguard Worker   //
68*795d594fSAndroid Build Coastguard Worker   /// CHECK-FI:
breakLoop(int[] a)69*795d594fSAndroid Build Coastguard Worker   static int breakLoop(int[] a) {
70*795d594fSAndroid Build Coastguard Worker     int l = 0;
71*795d594fSAndroid Build Coastguard Worker     int u = a.length - 1;
72*795d594fSAndroid Build Coastguard Worker     int i = l;
73*795d594fSAndroid Build Coastguard Worker     if (l <= u) {
74*795d594fSAndroid Build Coastguard Worker       while (true) {
75*795d594fSAndroid Build Coastguard Worker         a[i] = 1;
76*795d594fSAndroid Build Coastguard Worker         if (i == u) break;
77*795d594fSAndroid Build Coastguard Worker         i++;
78*795d594fSAndroid Build Coastguard Worker       }
79*795d594fSAndroid Build Coastguard Worker     }
80*795d594fSAndroid Build Coastguard Worker     return i;
81*795d594fSAndroid Build Coastguard Worker   }
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopDown(int[]) induction_var_analysis (before)
84*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
85*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
86*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<MOne:i\d+>> IntConstant -1                     loop:none
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Two:i\d+>>  IntConstant 2                      loop:none
88*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
89*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [{{i\d+}},<<AddI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
90*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
91*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Two>>] loop:<<Loop>>      outer_loop:none
92*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [<<Phi>>,<<Zero>>]        loop:<<Loop>>      outer_loop:none
93*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<NE>>]                        loop:<<Loop>>      outer_loop:none
94*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<MOne>>]             loop:<<Loop>>      outer_loop:none
95*795d594fSAndroid Build Coastguard Worker   //
96*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopDown(int[]) induction_var_analysis (after)
97*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                        loop:none
98*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                         loop:none
99*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<MOne:i\d+>> IntConstant -1                        loop:none
100*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Two:i\d+>>  IntConstant 2                         loop:none
101*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                   loop:none
102*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [{{i\d+}},<<AddI:i\d+>>]          loop:<<Loop:B\d+>> outer_loop:none
103*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GE:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Zero>>] loop:<<Loop>>      outer_loop:none
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<GE>>]                           loop:<<Loop>>      outer_loop:none
105*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]        loop:<<Loop>>      outer_loop:none
106*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Two>>]    loop:<<Loop>>      outer_loop:none
107*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<MOne>>]                loop:<<Loop>>      outer_loop:none
breakLoopDown(int[] a)108*795d594fSAndroid Build Coastguard Worker   static int breakLoopDown(int[] a) {
109*795d594fSAndroid Build Coastguard Worker     int l = 0;
110*795d594fSAndroid Build Coastguard Worker     int u = a.length - 1;
111*795d594fSAndroid Build Coastguard Worker     int i = u;
112*795d594fSAndroid Build Coastguard Worker     if (u >= l) {
113*795d594fSAndroid Build Coastguard Worker       while (true) {
114*795d594fSAndroid Build Coastguard Worker         a[i] = 2;
115*795d594fSAndroid Build Coastguard Worker         if (i == l) break;
116*795d594fSAndroid Build Coastguard Worker         i--;
117*795d594fSAndroid Build Coastguard Worker       }
118*795d594fSAndroid Build Coastguard Worker     }
119*795d594fSAndroid Build Coastguard Worker     return i;
120*795d594fSAndroid Build Coastguard Worker   }
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopSafeConst(int[]) induction_var_analysis (before)
123*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
124*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
125*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                        loop:none
126*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483631               loop:none
127*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483646               loop:none
128*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
129*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
130*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
131*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
132*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Three>>] loop:<<Loop>>      outer_loop:none
133*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>    NotEqual [<<Phi>>,<<L2>>]            loop:<<Loop>>      outer_loop:none
134*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                If [<<NE>>]                          loop:<<Loop>>      outer_loop:none
135*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
136*795d594fSAndroid Build Coastguard Worker   //
137*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopSafeConst(int[]) induction_var_analysis (after)
138*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                        loop:none
139*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
140*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                        loop:none
141*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483631               loop:none
142*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483646               loop:none
143*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
144*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<LE:z\d+>>    LessThanOrEqual [<<Phi>>,<<L2>>]     loop:<<Loop>>      outer_loop:none
145*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
146*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
147*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
148*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Three>>] loop:<<Loop>>      outer_loop:none
149*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
150*795d594fSAndroid Build Coastguard Worker   //
151*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.breakLoopSafeConst(int[]) loop_optimization (after)
152*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                          loop:none
153*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                           loop:none
154*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Three:i\d+>> IntConstant 3                           loop:none
155*795d594fSAndroid Build Coastguard Worker   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
156*795d594fSAndroid Build Coastguard Worker   //
157*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Three>>,{{j\d+}}]           loop:none
158*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile                                      loop:<<Loop:B\d+>> outer_loop:none
159*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                VecStore [<<Par>>,<<Phi:i\d+>>,<<Rep>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
160*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                            loop:<<Loop>>      outer_loop:none
161*795d594fSAndroid Build Coastguard Worker   //
162*795d594fSAndroid Build Coastguard Worker   /// CHECK-ELSE:
163*795d594fSAndroid Build Coastguard Worker   //
164*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Four:i\d+>>  IntConstant 4                           loop:none
165*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Three>>]          loop:none
166*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                VecStore [<<Par>>,<<Phi:i\d+>>,<<Rep>>] loop:<<Loop:B\d+>> outer_loop:none
167*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG:                Add [<<Phi>>,<<Four>>]                  loop:<<Loop>>      outer_loop:none
168*795d594fSAndroid Build Coastguard Worker   //
169*795d594fSAndroid Build Coastguard Worker   /// CHECK-FI:
breakLoopSafeConst(int[] a)170*795d594fSAndroid Build Coastguard Worker   static int breakLoopSafeConst(int[] a) {
171*795d594fSAndroid Build Coastguard Worker     int l = Integer.MAX_VALUE - 16;
172*795d594fSAndroid Build Coastguard Worker     int u = Integer.MAX_VALUE - 1;
173*795d594fSAndroid Build Coastguard Worker     int i = l;
174*795d594fSAndroid Build Coastguard Worker     if (l <= u) {  // will be removed by simplifier
175*795d594fSAndroid Build Coastguard Worker       while (true) {
176*795d594fSAndroid Build Coastguard Worker         a[i - l] = 3;
177*795d594fSAndroid Build Coastguard Worker         if (i == u) break;
178*795d594fSAndroid Build Coastguard Worker         i++;
179*795d594fSAndroid Build Coastguard Worker       }
180*795d594fSAndroid Build Coastguard Worker     }
181*795d594fSAndroid Build Coastguard Worker     return i;
182*795d594fSAndroid Build Coastguard Worker   }
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopUnsafeConst(int[]) induction_var_analysis (before)
185*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue                       loop:none
186*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>   IntConstant 1                        loop:none
187*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Four:i\d+>>  IntConstant 4                        loop:none
188*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L1:i\d+>>    IntConstant 2147483632               loop:none
189*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<L2:i\d+>>    IntConstant 2147483647               loop:none
190*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<L1>>,<<AddI:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
191*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Sub:i\d+>>   Sub [<<Phi>>,<<L1>>]                 loop:<<Loop>>      outer_loop:none
192*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>   NullCheck [<<Par>>]                  loop:<<Loop>>      outer_loop:none
193*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>   BoundsCheck [<<Sub>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
194*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                ArraySet [<<Nil>>,<<Bnd>>,<<Four>>]  loop:<<Loop>>      outer_loop:none
195*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>    NotEqual [<<Phi>>,<<L2>>]            loop:<<Loop>>      outer_loop:none
196*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                If [<<NE>>]                          loop:<<Loop>>      outer_loop:none
197*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>       Add [<<Phi>>,<<One>>]                loop:<<Loop>>      outer_loop:none
198*795d594fSAndroid Build Coastguard Worker   //
199*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopUnsafeConst(int[]) induction_var_analysis (after)
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                NotEqual
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                LessThanOrEqual
breakLoopUnsafeConst(int[] a)202*795d594fSAndroid Build Coastguard Worker   static int breakLoopUnsafeConst(int[] a) {
203*795d594fSAndroid Build Coastguard Worker     int l = Integer.MAX_VALUE - 15;
204*795d594fSAndroid Build Coastguard Worker     int u = Integer.MAX_VALUE;
205*795d594fSAndroid Build Coastguard Worker     int i = l;
206*795d594fSAndroid Build Coastguard Worker     if (l <= u) {  // will be removed by simplifier
207*795d594fSAndroid Build Coastguard Worker       while (true) {
208*795d594fSAndroid Build Coastguard Worker         a[i - l] = 4;
209*795d594fSAndroid Build Coastguard Worker         if (i == u) break;  // rewriting exit not safe!
210*795d594fSAndroid Build Coastguard Worker         i++;
211*795d594fSAndroid Build Coastguard Worker       }
212*795d594fSAndroid Build Coastguard Worker     }
213*795d594fSAndroid Build Coastguard Worker     return i;
214*795d594fSAndroid Build Coastguard Worker   }
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopNastyPhi(int[]) induction_var_analysis (before)
217*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                      loop:none
218*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                       loop:none
219*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                       loop:none
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Five:i\d+>> IntConstant 5                       loop:none
221*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<M123:i\d+>> IntConstant -123                    loop:none
222*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                 loop:none
223*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]        loop:<<Loop:B\d+>> outer_loop:none
224*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Wrap:i\d+>> Phi [<<M123>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
225*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]      loop:<<Loop>>      outer_loop:none
226*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               ArraySet [<<Nil>>,<<Bnd>>,<<Five>>] loop:<<Loop>>      outer_loop:none
227*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]         loop:<<Loop>>      outer_loop:none
228*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<NE>>]                         loop:<<Loop>>      outer_loop:none
229*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]               loop:<<Loop>>      outer_loop:none
230*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<M123>>,<<Wrap>>]             loop:none
231*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               Return [<<Comb>>]                   loop:none
232*795d594fSAndroid Build Coastguard Worker   //
233*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopNastyPhi(int[]) induction_var_analysis (after)
234*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               NotEqual
235*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:               LessThanOrEqual
breakLoopNastyPhi(int[] a)236*795d594fSAndroid Build Coastguard Worker   static int breakLoopNastyPhi(int[] a) {
237*795d594fSAndroid Build Coastguard Worker     int l = 0;
238*795d594fSAndroid Build Coastguard Worker     int u = a.length - 1;
239*795d594fSAndroid Build Coastguard Worker     int x = -123;
240*795d594fSAndroid Build Coastguard Worker     if (l <= u) {
241*795d594fSAndroid Build Coastguard Worker       int i = l;
242*795d594fSAndroid Build Coastguard Worker       while (true) {
243*795d594fSAndroid Build Coastguard Worker         a[i] = 5;
244*795d594fSAndroid Build Coastguard Worker         if (i == u) break;
245*795d594fSAndroid Build Coastguard Worker         x = i;
246*795d594fSAndroid Build Coastguard Worker         i++;
247*795d594fSAndroid Build Coastguard Worker       }
248*795d594fSAndroid Build Coastguard Worker     }
249*795d594fSAndroid Build Coastguard Worker     return x;  // keep another phi live
250*795d594fSAndroid Build Coastguard Worker   }
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopReduction(int[]) induction_var_analysis (before)
253*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                 loop:none
254*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                  loop:none
255*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                  loop:none
256*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                 loop:none
257*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Red:i\d+>>  Phi [<<Zero>>,<<RedI:i\d+>>]   loop:<<Loop:B\d+>> outer_loop:none
258*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]   loop:<<Loop>>      outer_loop:none
259*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
260*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Get:i\d+>>  ArrayGet [<<Nil>>,<<Bnd>>]     loop:<<Loop>>      outer_loop:none
261*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<RedI>>      Add [<<Red>>,<<Get>>]          loop:<<Loop>>      outer_loop:none
262*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<NE:z\d+>>   NotEqual [{{i\d+}},<<Phi>>]    loop:<<Loop>>      outer_loop:none
263*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<NE>>]                    loop:<<Loop>>      outer_loop:none
264*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]          loop:<<Loop>>      outer_loop:none
265*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<Zero>>,<<RedI>>]        loop:none
266*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               Return [<<Comb>>]              loop:none
267*795d594fSAndroid Build Coastguard Worker   //
268*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.breakLoopReduction(int[]) induction_var_analysis (after)
269*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>  ParameterValue                     loop:none
270*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0                      loop:none
271*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<One:i\d+>>  IntConstant 1                      loop:none
272*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Nil:l\d+>>  NullCheck [<<Par>>]                loop:none
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Red:i\d+>>  Phi [<<Zero>>,<<RedI:i\d+>>]       loop:<<Loop:B\d+>> outer_loop:none
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Phi:i\d+>>  Phi [<<Zero>>,<<AddI:i\d+>>]       loop:<<Loop>>      outer_loop:none
275*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<LE:z\d+>>   LessThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
276*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               If [<<LE>>]                        loop:<<Loop>>      outer_loop:none
277*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Bnd:i\d+>>  BoundsCheck [<<Phi>>,{{i\d+}}]     loop:<<Loop>>      outer_loop:none
278*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Get:i\d+>>  ArrayGet [<<Nil>>,<<Bnd>>]         loop:<<Loop>>      outer_loop:none
279*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<RedI>>      Add [<<Red>>,<<Get>>]              loop:<<Loop>>      outer_loop:none
280*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<AddI>>      Add [<<Phi>>,<<One>>]              loop:<<Loop>>      outer_loop:none
281*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Comb:i\d+>> Phi [<<Zero>>,<<Red>>]             loop:none
282*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:               Return [<<Comb>>]                  loop:none
283*795d594fSAndroid Build Coastguard Worker   //
284*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.breakLoopReduction(int[]) loop_optimization (after)
285*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Par:l\d+>>   ParameterValue              loop:none
286*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Zero:i\d+>>  IntConstant 0               loop:none
287*795d594fSAndroid Build Coastguard Worker   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
288*795d594fSAndroid Build Coastguard Worker   //
289*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Exp:d\d+>>   VecSetScalars [<<Zero>>,{{j\d+}}]     loop:none
290*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile                          loop:<<Loop:B\d+>> outer_loop:none
291*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VPhi:d\d+>>  Phi [<<Exp>>,<<VAdd:d\d+>>]           loop:<<Loop>>      outer_loop:none
292*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VLoad:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
293*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VAdd>>       VecAdd [<<VPhi>>,<<VLoad>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
294*795d594fSAndroid Build Coastguard Worker   //
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-ELSE:
296*795d594fSAndroid Build Coastguard Worker   //
297*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<Exp:d\d+>>   VecSetScalars [<<Zero>>]    loop:none
298*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VPhi:d\d+>>  Phi [<<Exp>>,<<VAdd:d\d+>>] loop:<<Loop:B\d+>> outer_loop:none
299*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VLoad:d\d+>> VecLoad                     loop:<<Loop>>      outer_loop:none
300*795d594fSAndroid Build Coastguard Worker   ///     CHECK-DAG: <<VAdd>>       VecAdd [<<VPhi>>,<<VLoad>>] loop:<<Loop>>      outer_loop:none
301*795d594fSAndroid Build Coastguard Worker   //
302*795d594fSAndroid Build Coastguard Worker   /// CHECK-FI:
breakLoopReduction(int[] a)303*795d594fSAndroid Build Coastguard Worker   static int breakLoopReduction(int[] a) {
304*795d594fSAndroid Build Coastguard Worker     int l = 0;
305*795d594fSAndroid Build Coastguard Worker     int u = a.length - 1;
306*795d594fSAndroid Build Coastguard Worker     int x = 0;
307*795d594fSAndroid Build Coastguard Worker     if (l <= u) {
308*795d594fSAndroid Build Coastguard Worker       int i = l;
309*795d594fSAndroid Build Coastguard Worker       while (true) {
310*795d594fSAndroid Build Coastguard Worker         x += a[i];
311*795d594fSAndroid Build Coastguard Worker         if (i == u) break;
312*795d594fSAndroid Build Coastguard Worker         i++;
313*795d594fSAndroid Build Coastguard Worker       }
314*795d594fSAndroid Build Coastguard Worker     }
315*795d594fSAndroid Build Coastguard Worker     return x;
316*795d594fSAndroid Build Coastguard Worker   }
317*795d594fSAndroid Build Coastguard Worker 
318*795d594fSAndroid Build Coastguard Worker   //
319*795d594fSAndroid Build Coastguard Worker   // Test driver.
320*795d594fSAndroid Build Coastguard Worker   //
321*795d594fSAndroid Build Coastguard Worker 
main(String[] args)322*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
323*795d594fSAndroid Build Coastguard Worker     int[] a = new int[100];
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker     expectEquals(99, breakLoop(a));
326*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
327*795d594fSAndroid Build Coastguard Worker       expectEquals(1, a[i]);
328*795d594fSAndroid Build Coastguard Worker     }
329*795d594fSAndroid Build Coastguard Worker 
330*795d594fSAndroid Build Coastguard Worker     expectEquals(0, breakLoopDown(a));
331*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
332*795d594fSAndroid Build Coastguard Worker       expectEquals(2, a[i]);
333*795d594fSAndroid Build Coastguard Worker     }
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker     expectEquals(Integer.MAX_VALUE - 1, breakLoopSafeConst(a));
336*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
337*795d594fSAndroid Build Coastguard Worker       int e = i < 16 ? 3 : 2;
338*795d594fSAndroid Build Coastguard Worker       expectEquals(e, a[i]);
339*795d594fSAndroid Build Coastguard Worker     }
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker     expectEquals(Integer.MAX_VALUE, breakLoopUnsafeConst(a));
342*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
343*795d594fSAndroid Build Coastguard Worker       int e = i < 16 ? 4 : 2;
344*795d594fSAndroid Build Coastguard Worker       expectEquals(e, a[i]);
345*795d594fSAndroid Build Coastguard Worker     }
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker     expectEquals(98, breakLoopNastyPhi(a));
348*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
349*795d594fSAndroid Build Coastguard Worker       expectEquals(5, a[i]);
350*795d594fSAndroid Build Coastguard Worker     }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker     expectEquals(500, breakLoopReduction(a));
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker     System.out.println("passed");
355*795d594fSAndroid Build Coastguard Worker   }
356*795d594fSAndroid Build Coastguard Worker 
357*795d594fSAndroid Build Coastguard Worker   private static void expectEquals(int expected, int result) {
358*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
359*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
360*795d594fSAndroid Build Coastguard Worker     }
361*795d594fSAndroid Build Coastguard Worker   }
362*795d594fSAndroid Build Coastguard Worker }
363