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 import java.lang.reflect.Array;
17 import java.lang.reflect.Method;
18 
19 /**
20  * Tests for SIMD related optimizations.
21  */
22 public class Main {
23 
24   /// CHECK-START: void Main.unroll(float[], float[]) loop_optimization (before)
25   /// CHECK-DAG: <<Cons:f\d+>> FloatConstant 2.5                   loop:none
26   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
27   /// CHECK-DAG: <<Get:f\d+>>  ArrayGet                            loop:<<Loop>>      outer_loop:none
28   /// CHECK-DAG: <<Mul:f\d+>>  Mul [<<Get>>,<<Cons>>]              loop:<<Loop>>      outer_loop:none
29   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Mul>>] loop:<<Loop>>      outer_loop:none
30   //
31   /// CHECK-START-ARM64: void Main.unroll(float[], float[]) loop_optimization (after)
32   /// CHECK-DAG: <<Cons:f\d+>> FloatConstant 2.5                    loop:none
33 
34   /// CHECK-IF:     hasIsaFeature("sve")
35   //
36   ///     CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<Cons>>,{{j\d+}}]         loop:none
37   ///     CHECK-NOT:                VecReplicateScalar
38   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                            loop:<<Loop:B\d+>> outer_loop:none
39   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                loop:<<Loop>>      outer_loop:none
40   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
41   ///     CHECK-DAG: <<Mul1:d\d+>>  VecMul [<<Get1>>,<<Repl>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
42   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Mul1>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
43   ///     CHECK-DAG: <<Add:i\d+>>   Add [<<Phi>>,{{i\d+}}]                         loop:<<Loop>>      outer_loop:none
44   //      No unroll for SVE yet.
45   //
46   /// CHECK-ELSE:
47   //
48   ///     CHECK-DAG: <<Incr:i\d+>>  IntConstant 4                        loop:none
49   ///     CHECK-DAG: <<Repl:d\d+>>  VecReplicateScalar [<<Cons>>]        loop:none
50   ///     CHECK-NOT:                VecReplicateScalar
51   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                  loop:<<Loop:B\d+>> outer_loop:none
52   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]           loop:<<Loop>>      outer_loop:none
53   ///     CHECK-DAG: <<Mul1:d\d+>>  VecMul [<<Get1>>,<<Repl>>]           loop:<<Loop>>      outer_loop:none
54   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Mul1>>] loop:<<Loop>>      outer_loop:none
55   ///     CHECK-DAG: <<Add:i\d+>>   Add [<<Phi>>,<<Incr>>]               loop:<<Loop>>      outer_loop:none
56   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add>>]           loop:<<Loop>>      outer_loop:none
57   ///     CHECK-DAG: <<Mul2:d\d+>>  VecMul [<<Get2>>,<<Repl>>]           loop:<<Loop>>      outer_loop:none
58   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add>>,<<Mul2>>] loop:<<Loop>>      outer_loop:none
59   ///     CHECK-DAG:                Add [<<Add>>,<<Incr>>]               loop:<<Loop>>      outer_loop:none
60   //
61   /// CHECK-FI:
unroll(float[] x, float[] y)62   private static void unroll(float[] x, float[] y) {
63     for (int i = 0; i < 100; i++) {
64       x[i] = y[i] * 2.5f;
65     }
66   }
67 
68   /// CHECK-START-ARM64: void Main.stencil(int[], int[], int) loop_optimization (after)
69   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                         loop:none
70   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2                         loop:none
71   /// CHECK-IF:     hasIsaFeature("sve")
72   //
73   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                             loop:<<Loop:B\d+>> outer_loop:none
74   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
75   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                           loop:<<Loop>>      outer_loop:none
76   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
77   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
78   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
79   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                           loop:<<Loop>>      outer_loop:none
80   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
81   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
82   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
83   //
84   /// CHECK-ELSE:
85   //
86   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                   loop:<<Loop:B\d+>> outer_loop:none
87   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                 loop:<<Loop>>      outer_loop:none
88   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]            loop:<<Loop>>      outer_loop:none
89   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]           loop:<<Loop>>      outer_loop:none
90   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]            loop:<<Loop>>      outer_loop:none
91   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                 loop:<<Loop>>      outer_loop:none
92   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]           loop:<<Loop>>      outer_loop:none
93   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]            loop:<<Loop>>      outer_loop:none
94   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
95   //
96   /// CHECK-FI:
stencil(int[] a, int[] b, int n)97   private static void stencil(int[] a, int[] b, int n) {
98     for (int i = 1; i < n - 1; i++) {
99       a[i] = b[i - 1] + b[i] + b[i + 1];
100     }
101   }
102 
103   /// CHECK-START: void Main.stencilAddInt(int[], int[], int) loop_optimization (before)
104   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                        loop:none
105   /// CHECK-DAG: <<CM1:i\d+>>   IntConstant -1                       loop:none
106   /// CHECK-DAG: <<Phi:i\d+>>   Phi                                  loop:<<Loop:B\d+>> outer_loop:none
107   /// CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CM1>>]                loop:<<Loop>>      outer_loop:none
108   /// CHECK-DAG: <<Get1:i\d+>>  ArrayGet [{{l\d+}},<<Add1>>]         loop:<<Loop>>      outer_loop:none
109   /// CHECK-DAG: <<Get2:i\d+>>  ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
110   /// CHECK-DAG: <<Add2:i\d+>>  Add [<<Get1>>,<<Get2>>]              loop:<<Loop>>      outer_loop:none
111   /// CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
112   /// CHECK-DAG: <<Get3:i\d+>>  ArrayGet [{{l\d+}},<<Add3>>]         loop:<<Loop>>      outer_loop:none
113   /// CHECK-DAG: <<Add4:i\d+>>  Add [<<Add2>>,<<Get3>>]              loop:<<Loop>>      outer_loop:none
114   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
115 
116   /// CHECK-START-{X86_64,ARM64}: void Main.stencilAddInt(int[], int[], int) loop_optimization (after)
117   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                         loop:none
118   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2                         loop:none
119   /// CHECK-IF:     hasIsaFeature("sve")
120   //
121   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                             loop:<<Loop:B\d+>> outer_loop:none
122   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
123   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                           loop:<<Loop>>      outer_loop:none
124   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
125   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
126   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
127   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                           loop:<<Loop>>      outer_loop:none
128   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
129   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
130   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
131   //
132   /// CHECK-ELSE:
133   //
134   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                   loop:<<Loop:B\d+>> outer_loop:none
135   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                 loop:<<Loop>>      outer_loop:none
136   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]            loop:<<Loop>>      outer_loop:none
137   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]           loop:<<Loop>>      outer_loop:none
138   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]            loop:<<Loop>>      outer_loop:none
139   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                 loop:<<Loop>>      outer_loop:none
140   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]           loop:<<Loop>>      outer_loop:none
141   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]            loop:<<Loop>>      outer_loop:none
142   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
143   //
144   /// CHECK-FI:
stencilAddInt(int[] a, int[] b, int n)145   private static void stencilAddInt(int[] a, int[] b, int n) {
146     int minus1 = $inline$constMinus1();
147     for (int i = 1; i < n + minus1; i++) {
148       a[i] = b[i + minus1] + b[i] + b[i + 1];
149     }
150   }
151 
$inline$constMinus1()152   private static int $inline$constMinus1() {
153     return -1;
154   }
155 
156   /// CHECK-START: void Main.stencilSubInt(int[], int[], int) loop_optimization (before)
157   /// CHECK-DAG: <<PAR3:i\d+>>  ParameterValue                       loop:none
158   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                        loop:none
159   /// CHECK-DAG: <<Sub1:i\d+>>  Sub [<<PAR3>>,<<CP1>>]               loop:none
160   /// CHECK-DAG: <<Phi:i\d+>>   Phi                                  loop:<<Loop:B\d+>> outer_loop:none
161   /// CHECK-DAG: <<Sub2:i\d+>>  Sub [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
162   /// CHECK-DAG: <<Get1:i\d+>>  ArrayGet [{{l\d+}},<<Sub2>>]         loop:<<Loop>>      outer_loop:none
163   /// CHECK-DAG: <<Get2:i\d+>>  ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
164   /// CHECK-DAG: <<Add1:i\d+>>  Add [<<Get1>>,<<Get2>>]              loop:<<Loop>>      outer_loop:none
165   /// CHECK-DAG: <<Add2:i\d+>>  Add [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
166   /// CHECK-DAG: <<Get3:i\d+>>  ArrayGet [{{l\d+}},<<Add2>>]         loop:<<Loop>>      outer_loop:none
167   /// CHECK-DAG: <<Add3:i\d+>>  Add [<<Add1>>,<<Get3>>]              loop:<<Loop>>      outer_loop:none
168   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Add3>>] loop:<<Loop>>      outer_loop:none
169 
170   /// CHECK-START-{X86_64,ARM64}: void Main.stencilSubInt(int[], int[], int) loop_optimization (after)
171   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                         loop:none
172   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2                         loop:none
173   /// CHECK-IF:     hasIsaFeature("sve")
174   //
175   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                             loop:<<Loop:B\d+>> outer_loop:none
176   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
177   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                           loop:<<Loop>>      outer_loop:none
178   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
179   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
180   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
181   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                           loop:<<Loop>>      outer_loop:none
182   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
183   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
184   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
185   //
186   /// CHECK-ELSE:
187   //
188   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                   loop:<<Loop:B\d+>> outer_loop:none
189   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                 loop:<<Loop>>      outer_loop:none
190   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]            loop:<<Loop>>      outer_loop:none
191   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]           loop:<<Loop>>      outer_loop:none
192   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]            loop:<<Loop>>      outer_loop:none
193   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                 loop:<<Loop>>      outer_loop:none
194   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]           loop:<<Loop>>      outer_loop:none
195   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]            loop:<<Loop>>      outer_loop:none
196   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
197   //
198   /// CHECK-FI:
stencilSubInt(int[] a, int[] b, int n)199   private static void stencilSubInt(int[] a, int[] b, int n) {
200     int plus1 = $inline$constPlus1();
201     for (int i = 1; i < n - plus1; i++) {
202       a[i] = b[i - plus1] + b[i] + b[i + 1];
203     }
204   }
205 
$inline$constPlus1()206   private static int $inline$constPlus1() {
207     return 1;
208   }
209 
210   /// CHECK-START: long Main.longInductionReduction(long[]) loop_optimization (before)
211   /// CHECK-DAG: <<L0:j\d+>>    LongConstant 0             loop:none
212   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1             loop:none
213   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0              loop:none
214   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>] loop:none
215   /// CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,<<Add1:j\d+>>] loop:<<Loop:B\d+>> outer_loop:none
216   /// CHECK-DAG: <<Phi2:j\d+>>  Phi [<<L1>>,<<Add2:j\d+>>] loop:<<Loop>>      outer_loop:none
217   /// CHECK-DAG: <<Add2>>       Add [<<Phi2>>,<<Get>>]     loop:<<Loop>>      outer_loop:none
218   /// CHECK-DAG: <<Add1>>       Add [<<Phi1>>,<<L1>>]      loop:<<Loop>>      outer_loop:none
219   //
220   /// CHECK-START-ARM64: long Main.longInductionReduction(long[]) loop_optimization (after)
221   /// CHECK-DAG: <<L0:j\d+>>    LongConstant 0               loop:none
222   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1               loop:none
223   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                loop:none
224   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]   loop:none
225   /// CHECK-IF:     hasIsaFeature("sve")
226   //
227   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Get>>,{{j\d+}}]  loop:none
228   ///     CHECK-DAG: <<Set:d\d+>>   VecSetScalars [<<L1>>,{{j\d+}}]        loop:none
229   ///     CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,{{j\d+}}]                  loop:<<Loop:B\d+>> outer_loop:none
230   ///     CHECK-DAG: <<Phi2:d\d+>>  Phi [<<Set>>,{{d\d+}}]                 loop:<<Loop>>      outer_loop:none
231   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi1>>,{{j\d+}}]       loop:<<Loop>>      outer_loop:none
232   ///     CHECK-DAG:                VecAdd [<<Phi2>>,<<Rep>>,<<LoopP>>]    loop:<<Loop>>      outer_loop:none
233   ///     CHECK-DAG:                Add [<<Phi1>>,{{j\d+}}]                loop:<<Loop>>      outer_loop:none
234   //
235   /// CHECK-ELSE:
236   //
237   ///     CHECK-DAG: <<L2:j\d+>>    LongConstant 2               loop:none
238   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Get>>] loop:none
239   ///     CHECK-DAG: <<Set:d\d+>>   VecSetScalars [<<L1>>]       loop:none
240   ///     CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,{{j\d+}}]        loop:<<Loop:B\d+>> outer_loop:none
241   ///     CHECK-DAG: <<Phi2:d\d+>>  Phi [<<Set>>,{{d\d+}}]       loop:<<Loop>>      outer_loop:none
242   ///     CHECK-DAG:                VecAdd [<<Phi2>>,<<Rep>>]    loop:<<Loop>>      outer_loop:none
243   ///     CHECK-DAG:                Add [<<Phi1>>,<<L2>>]        loop:<<Loop>>      outer_loop:none
244   //
245   /// CHECK-FI:
longInductionReduction(long[] y)246   static long longInductionReduction(long[] y) {
247     long x = 1;
248     for (long i = 0; i < 10; i++) {
249       x += y[0];
250     }
251     return x;
252   }
253 
254   /// CHECK-START: void Main.intVectorLongInvariant(int[], long[]) loop_optimization (before)
255   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
256   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                       loop:none
257   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]          loop:none
258   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,<<Add:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
259   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<Get>>]            loop:<<Loop>>      outer_loop:none
260   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
261   /// CHECK-DAG: <<Add>>        Add [<<Phi>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
262   //
263   /// CHECK-START-ARM64: void Main.intVectorLongInvariant(int[], long[]) loop_optimization (after)
264   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
265   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                       loop:none
266   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]          loop:none
267   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<Get>>]            loop:none
268   /// CHECK-IF:     hasIsaFeature("sve")
269   //
270   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>,{{j\d+}}]         loop:none
271   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]                         loop:<<Loop:B\d+>> outer_loop:none
272   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
273   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Rep>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
274   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                        loop:<<Loop>>      outer_loop:none
275   //
276   /// CHECK-ELSE:
277   //
278   ///     CHECK-DAG: <<I4:i\d+>>    IntConstant 4                       loop:none
279   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>]        loop:none
280   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]               loop:<<Loop:B\d+>> outer_loop:none
281   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Rep>>] loop:<<Loop>>      outer_loop:none
282   ///     CHECK-DAG:                Add [<<Phi>>,<<I4>>]                loop:<<Loop>>      outer_loop:none
283   //
284   /// CHECK-FI:
intVectorLongInvariant(int[] x, long[] y)285   static void intVectorLongInvariant(int[] x, long[] y) {
286     for (int i = 0; i < 100; i++) {
287       x[i] = (int) y[0];
288     }
289   }
290 
291   /// CHECK-START: void Main.longCanBeDoneWithInt(int[], int[]) loop_optimization (before)
292   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                        loop:none
293   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                        loop:none
294   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1                       loop:none
295   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,<<Add:i\d+>>]            loop:<<Loop:B\d+>> outer_loop:none
296   /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
297   /// CHECK-DAG: <<Cnv1:j\d+>>  TypeConversion [<<Get>>]             loop:<<Loop>>      outer_loop:none
298   /// CHECK-DAG: <<AddL:j\d+>>  Add [<<Cnv1>>,<<L1>>]                loop:<<Loop>>      outer_loop:none
299   /// CHECK-DAG: <<Cnv2:i\d+>>  TypeConversion [<<AddL>>]            loop:<<Loop>>      outer_loop:none
300   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Cnv2>>] loop:<<Loop>>      outer_loop:none
301   /// CHECK-DAG: <<Add>>        Add [<<Phi>>,<<I1>>]                 loop:<<Loop>>      outer_loop:none
302   //
303   /// CHECK-START-ARM64: void Main.longCanBeDoneWithInt(int[], int[]) loop_optimization (after)
304   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
305   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1                      loop:none
306   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<L1>>]             loop:none
307   /// CHECK-IF:     hasIsaFeature("sve")
308   //
309   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>,{{j\d+}}]         loop:none
310   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]                         loop:<<Loop:B\d+>> outer_loop:none
311   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
312   ///     CHECK-DAG: <<Load:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]          loop:<<Loop>>      outer_loop:none
313   ///     CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Rep>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
314   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Add>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
315   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                        loop:<<Loop>>      outer_loop:none
316   //
317   /// CHECK-ELSE:
318   //
319   ///     CHECK-DAG: <<I4:i\d+>>    IntConstant 4                       loop:none
320   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>]        loop:none
321   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]               loop:<<Loop:B\d+>> outer_loop:none
322   ///     CHECK-DAG: <<Load:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
323   ///     CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Rep>>]           loop:<<Loop>>      outer_loop:none
324   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>>      outer_loop:none
325   ///     CHECK-DAG:                Add [<<Phi>>,<<I4>>]                loop:<<Loop>>      outer_loop:none
326   //
327   /// CHECK-FI:
longCanBeDoneWithInt(int[] x, int[] y)328   static void longCanBeDoneWithInt(int[] x, int[] y) {
329     for (int i = 0; i < 100; i++) {
330       x[i] = (int) (y[i] + 1L);
331     }
332   }
333 
testUnroll()334   static void testUnroll() {
335     float[] x = new float[100];
336     float[] y = new float[100];
337     for (int i = 0; i < 100; i++) {
338       x[i] = 0.0f;
339       y[i] = 2.0f;
340     }
341     unroll(x, y);
342     for (int i = 0; i < 100; i++) {
343       expectEquals(5.0f, x[i]);
344       expectEquals(2.0f, y[i]);
345     }
346   }
347 
testStencil1()348   static void testStencil1() {
349     int[] a = new int[100];
350     int[] b = new int[100];
351     for (int i = 0; i < 100; i++) {
352       a[i] = 0;
353       b[i] = i;
354     }
355     stencil(a, b, 100);
356     for (int i = 1; i < 99; i++) {
357       int e = i + i + i;
358       expectEquals(e, a[i]);
359       expectEquals(i, b[i]);
360     }
361   }
362 
testStencil2()363   static void testStencil2() {
364     int[] a = new int[100];
365     int[] b = new int[100];
366     for (int i = 0; i < 100; i++) {
367       a[i] = 0;
368       b[i] = i;
369     }
370     stencilSubInt(a, b, 100);
371     for (int i = 1; i < 99; i++) {
372       int e = i + i + i;
373       expectEquals(e, a[i]);
374       expectEquals(i, b[i]);
375     }
376   }
377 
testStencil3()378   static void testStencil3() {
379     int[] a = new int[100];
380     int[] b = new int[100];
381     for (int i = 0; i < 100; i++) {
382       a[i] = 0;
383       b[i] = i;
384     }
385     stencilAddInt(a, b, 100);
386     for (int i = 1; i < 99; i++) {
387       int e = i + i + i;
388       expectEquals(e, a[i]);
389       expectEquals(i, b[i]);
390     }
391   }
392 
testTypes()393   static void testTypes() {
394     int[] a = new int[100];
395     int[] b = new int[100];
396     long[] l = { 3 };
397     expectEquals(31, longInductionReduction(l));
398     intVectorLongInvariant(a, l);
399     for (int i = 0; i < 100; i++) {
400       expectEquals(3, a[i]);
401     }
402     longCanBeDoneWithInt(b, a);
403     for (int i = 0; i < 100; i++) {
404       expectEquals(4, b[i]);
405     }
406   }
407 
main(String[] args)408   public static void main(String[] args) {
409     testUnroll();
410     testStencil1();
411     testStencil2();
412     testStencil3();
413     testTypes();
414     System.out.println("passed");
415   }
416 
expectEquals(int expected, int result)417   private static void expectEquals(int expected, int result) {
418     if (expected != result) {
419       throw new Error("Expected: " + expected + ", found: " + result);
420     }
421   }
422 
expectEquals(long expected, long result)423   private static void expectEquals(long expected, long result) {
424     if (expected != result) {
425       throw new Error("Expected: " + expected + ", found: " + result);
426     }
427   }
428 
expectEquals(float expected, float result)429   private static void expectEquals(float expected, float result) {
430     if (expected != result) {
431       throw new Error("Expected: " + expected + ", found: " + result);
432     }
433   }
434 }
435