xref: /aosp_15_r20/art/test/656-checker-simd-opt/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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-{X86_64,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") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
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-{X86_64,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") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
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   // Array size is chosen to be such a constant, that the loop trip count (in the test below)
104   // is a multiple of vector length and unroll factor; hence clean up is needed exclusively for
105   // the array references test.
106   public static final int STENCIL_ARRAY_SIZE = 130;
107 
108   /// CHECK-START-{X86_64,ARM64}: void Main.$noinline$stencilConstSize(int[], int[]) loop_optimization (after)
109   /// CHECK-DAG: <<C0:i\d+>>    IntConstant 0
110   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1
111   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2
112   /// CHECK-DAG: <<Arr0:l\d+>>  ParameterValue
113   /// CHECK-DAG: <<Arr1:l\d+>>  ParameterValue
114   /// CHECK-DAG: <<ArrCh:z\d+>> NotEqual [<<Arr0>>,<<Arr1>>]         loop:none
115   /// CHECK-DAG: <<TCSel:i\d+>> Select [<<C0>>,{{i\d+}},<<ArrCh>>]   loop:none
116   /// CHECK-DAG: <<PhiV:i\d+>>  Phi [<<C0>>,{{i\d+}}]                loop:<<LoopV:B\d+>> outer_loop:none
117   //
118   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
119   //
120   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<PhiV>>,{{i\d+}}]                loop:<<LoopV>>      outer_loop:none
121   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<PhiV>>,<<CP1>>]                          loop:<<LoopV>>      outer_loop:none
122   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<PhiV>>,<<LoopP>>]           loop:<<LoopV>>      outer_loop:none
123   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<LoopV>>      outer_loop:none
124   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<LoopV>>      outer_loop:none
125   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<PhiV>>,<<CP2>>]                          loop:<<LoopV>>      outer_loop:none
126   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<LoopV>>      outer_loop:none
127   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<LoopV>>      outer_loop:none
128   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<LoopV>>      outer_loop:none
129   //
130   /// CHECK-ELSE:
131   //
132   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<PhiV>>,<<CP1>>]                          loop:<<LoopV>>      outer_loop:none
133   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<PhiV>>]                     loop:<<LoopV>>      outer_loop:none
134   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]                     loop:<<LoopV>>      outer_loop:none
135   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]                      loop:<<LoopV>>      outer_loop:none
136   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<PhiV>>,<<CP2>>]                          loop:<<LoopV>>      outer_loop:none
137   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]                     loop:<<LoopV>>      outer_loop:none
138   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]                      loop:<<LoopV>>      outer_loop:none
139   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>]           loop:<<LoopV>>      outer_loop:none
140   //
141   /// CHECK-FI:
142   //
143   // Cleanup loop.
144   //
145   /// CHECK-DAG: <<PhiS:i\d+>>   Phi [<<PhiV>>,{{i\d+}}]             loop:<<LoopS:B\d+>> outer_loop:none
146   /// CHECK-DAG:                 ArrayGet                            loop:<<LoopS>>      outer_loop:none
147   /// CHECK-DAG:                 ArrayGet                            loop:<<LoopS>>      outer_loop:none
148   /// CHECK-DAG:                 ArrayGet                            loop:<<LoopS>>      outer_loop:none
149   /// CHECK-DAG:                 ArraySet                            loop:<<LoopS>>      outer_loop:none
150   //
151   // Checks the disambiguation runtime test for array references.
152   //
$noinline$stencilConstSize(int[] a, int[] b)153   private static void $noinline$stencilConstSize(int[] a, int[] b) {
154     for (int i = 1; i < STENCIL_ARRAY_SIZE - 1; i++) {
155       a[i] = b[i - 1] + b[i] + b[i + 1];
156     }
157   }
158 
159   /// CHECK-START: void Main.stencilAddInt(int[], int[], int) loop_optimization (before)
160   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                        loop:none
161   /// CHECK-DAG: <<CM1:i\d+>>   IntConstant -1                       loop:none
162   /// CHECK-DAG: <<Phi:i\d+>>   Phi                                  loop:<<Loop:B\d+>> outer_loop:none
163   /// CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CM1>>]                loop:<<Loop>>      outer_loop:none
164   /// CHECK-DAG: <<Get1:i\d+>>  ArrayGet [{{l\d+}},<<Add1>>]         loop:<<Loop>>      outer_loop:none
165   /// CHECK-DAG: <<Get2:i\d+>>  ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
166   /// CHECK-DAG: <<Add2:i\d+>>  Add [<<Get1>>,<<Get2>>]              loop:<<Loop>>      outer_loop:none
167   /// CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
168   /// CHECK-DAG: <<Get3:i\d+>>  ArrayGet [{{l\d+}},<<Add3>>]         loop:<<Loop>>      outer_loop:none
169   /// CHECK-DAG: <<Add4:i\d+>>  Add [<<Add2>>,<<Get3>>]              loop:<<Loop>>      outer_loop:none
170   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
171 
172   /// CHECK-START-{X86_64,ARM64}: void Main.stencilAddInt(int[], int[], int) loop_optimization (after)
173   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                         loop:none
174   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2                         loop:none
175   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
176   //
177   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                             loop:<<Loop:B\d+>> outer_loop:none
178   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
179   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                           loop:<<Loop>>      outer_loop:none
180   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
181   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
182   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
183   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                           loop:<<Loop>>      outer_loop:none
184   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
185   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
186   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
187   //
188   /// CHECK-ELSE:
189   //
190   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                   loop:<<Loop:B\d+>> outer_loop:none
191   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                 loop:<<Loop>>      outer_loop:none
192   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]            loop:<<Loop>>      outer_loop:none
193   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]           loop:<<Loop>>      outer_loop:none
194   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]            loop:<<Loop>>      outer_loop:none
195   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                 loop:<<Loop>>      outer_loop:none
196   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]           loop:<<Loop>>      outer_loop:none
197   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]            loop:<<Loop>>      outer_loop:none
198   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
199   //
200   /// CHECK-FI:
stencilAddInt(int[] a, int[] b, int n)201   private static void stencilAddInt(int[] a, int[] b, int n) {
202     int minus1 = $inline$constMinus1();
203     for (int i = 1; i < n + minus1; i++) {
204       a[i] = b[i + minus1] + b[i] + b[i + 1];
205     }
206   }
207 
$inline$constMinus1()208   private static int $inline$constMinus1() {
209     return -1;
210   }
211 
212   /// CHECK-START: void Main.stencilSubInt(int[], int[], int) loop_optimization (before)
213   /// CHECK-DAG: <<PAR3:i\d+>>  ParameterValue                       loop:none
214   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                        loop:none
215   /// CHECK-DAG: <<Sub1:i\d+>>  Sub [<<PAR3>>,<<CP1>>]               loop:none
216   /// CHECK-DAG: <<Phi:i\d+>>   Phi                                  loop:<<Loop:B\d+>> outer_loop:none
217   /// CHECK-DAG: <<Sub2:i\d+>>  Sub [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
218   /// CHECK-DAG: <<Get1:i\d+>>  ArrayGet [{{l\d+}},<<Sub2>>]         loop:<<Loop>>      outer_loop:none
219   /// CHECK-DAG: <<Get2:i\d+>>  ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
220   /// CHECK-DAG: <<Add1:i\d+>>  Add [<<Get1>>,<<Get2>>]              loop:<<Loop>>      outer_loop:none
221   /// CHECK-DAG: <<Add2:i\d+>>  Add [<<Phi>>,<<CP1>>]                loop:<<Loop>>      outer_loop:none
222   /// CHECK-DAG: <<Get3:i\d+>>  ArrayGet [{{l\d+}},<<Add2>>]         loop:<<Loop>>      outer_loop:none
223   /// CHECK-DAG: <<Add3:i\d+>>  Add [<<Add1>>,<<Get3>>]              loop:<<Loop>>      outer_loop:none
224   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Add3>>] loop:<<Loop>>      outer_loop:none
225 
226   /// CHECK-START-{X86_64,ARM64}: void Main.stencilSubInt(int[], int[], int) loop_optimization (after)
227   /// CHECK-DAG: <<CP1:i\d+>>   IntConstant 1                         loop:none
228   /// CHECK-DAG: <<CP2:i\d+>>   IntConstant 2                         loop:none
229   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
230   //
231   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                             loop:<<Loop:B\d+>> outer_loop:none
232   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
233   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                           loop:<<Loop>>      outer_loop:none
234   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
235   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
236   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
237   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                           loop:<<Loop>>      outer_loop:none
238   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
239   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>,<<LoopP>>]            loop:<<Loop>>      outer_loop:none
240   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
241   //
242   /// CHECK-ELSE:
243   //
244   ///     CHECK-DAG: <<Phi:i\d+>>   Phi                                   loop:<<Loop:B\d+>> outer_loop:none
245   ///     CHECK-DAG: <<Add1:i\d+>>  Add [<<Phi>>,<<CP1>>]                 loop:<<Loop>>      outer_loop:none
246   ///     CHECK-DAG: <<Get1:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]            loop:<<Loop>>      outer_loop:none
247   ///     CHECK-DAG: <<Get2:d\d+>>  VecLoad [{{l\d+}},<<Add1>>]           loop:<<Loop>>      outer_loop:none
248   ///     CHECK-DAG: <<Add2:d\d+>>  VecAdd [<<Get1>>,<<Get2>>]            loop:<<Loop>>      outer_loop:none
249   ///     CHECK-DAG: <<Add3:i\d+>>  Add [<<Phi>>,<<CP2>>]                 loop:<<Loop>>      outer_loop:none
250   ///     CHECK-DAG: <<Get3:d\d+>>  VecLoad [{{l\d+}},<<Add3>>]           loop:<<Loop>>      outer_loop:none
251   ///     CHECK-DAG: <<Add4:d\d+>>  VecAdd [<<Add2>>,<<Get3>>]            loop:<<Loop>>      outer_loop:none
252   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Add1>>,<<Add4>>] loop:<<Loop>>      outer_loop:none
253   //
254   /// CHECK-FI:
stencilSubInt(int[] a, int[] b, int n)255   private static void stencilSubInt(int[] a, int[] b, int n) {
256     int plus1 = $inline$constPlus1();
257     for (int i = 1; i < n - plus1; i++) {
258       a[i] = b[i - plus1] + b[i] + b[i + 1];
259     }
260   }
261 
$inline$constPlus1()262   private static int $inline$constPlus1() {
263     return 1;
264   }
265 
266   /// CHECK-START: long Main.longInductionReduction(long[]) loop_optimization (before)
267   /// CHECK-DAG: <<L0:j\d+>>    LongConstant 0             loop:none
268   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1             loop:none
269   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0              loop:none
270   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>] loop:none
271   /// CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,<<Add1:j\d+>>] loop:<<Loop:B\d+>> outer_loop:none
272   /// CHECK-DAG: <<Phi2:j\d+>>  Phi [<<L1>>,<<Add2:j\d+>>] loop:<<Loop>>      outer_loop:none
273   /// CHECK-DAG: <<Add2>>       Add [<<Phi2>>,<<Get>>]     loop:<<Loop>>      outer_loop:none
274   /// CHECK-DAG: <<Add1>>       Add [<<Phi1>>,<<L1>>]      loop:<<Loop>>      outer_loop:none
275   //
276   /// CHECK-START-{X86_64,ARM64}: long Main.longInductionReduction(long[]) loop_optimization (after)
277   /// CHECK-DAG: <<L0:j\d+>>    LongConstant 0               loop:none
278   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1               loop:none
279   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                loop:none
280   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]   loop:none
281   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
282   //
283   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Get>>,{{j\d+}}]  loop:none
284   ///     CHECK-DAG: <<Set:d\d+>>   VecSetScalars [<<L1>>,{{j\d+}}]        loop:none
285   ///     CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,{{j\d+}}]                  loop:<<Loop:B\d+>> outer_loop:none
286   ///     CHECK-DAG: <<Phi2:d\d+>>  Phi [<<Set>>,{{d\d+}}]                 loop:<<Loop>>      outer_loop:none
287   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi1>>,{{j\d+}}]       loop:<<Loop>>      outer_loop:none
288   ///     CHECK-DAG:                VecAdd [<<Phi2>>,<<Rep>>,<<LoopP>>]    loop:<<Loop>>      outer_loop:none
289   ///     CHECK-DAG:                Add [<<Phi1>>,{{j\d+}}]                loop:<<Loop>>      outer_loop:none
290   //
291   /// CHECK-ELSE:
292   //
293   ///     CHECK-DAG: <<L2:j\d+>>    LongConstant 2               loop:none
294   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Get>>] loop:none
295   ///     CHECK-DAG: <<Set:d\d+>>   VecSetScalars [<<L1>>]       loop:none
296   ///     CHECK-DAG: <<Phi1:j\d+>>  Phi [<<L0>>,{{j\d+}}]        loop:<<Loop:B\d+>> outer_loop:none
297   ///     CHECK-DAG: <<Phi2:d\d+>>  Phi [<<Set>>,{{d\d+}}]       loop:<<Loop>>      outer_loop:none
298   ///     CHECK-DAG:                VecAdd [<<Phi2>>,<<Rep>>]    loop:<<Loop>>      outer_loop:none
299   ///     CHECK-DAG:                Add [<<Phi1>>,<<L2>>]        loop:<<Loop>>      outer_loop:none
300   //
301   /// CHECK-FI:
longInductionReduction(long[] y)302   static long longInductionReduction(long[] y) {
303     long x = 1;
304     for (long i = 0; i < 10; i++) {
305       x += y[0];
306     }
307     return x;
308   }
309 
310   /// CHECK-START: void Main.intVectorLongInvariant(int[], long[]) loop_optimization (before)
311   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
312   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                       loop:none
313   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]          loop:none
314   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,<<Add:i\d+>>]           loop:<<Loop:B\d+>> outer_loop:none
315   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<Get>>]            loop:<<Loop>>      outer_loop:none
316   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
317   /// CHECK-DAG: <<Add>>        Add [<<Phi>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
318   //
319   /// CHECK-START-{X86_64,ARM64}: void Main.intVectorLongInvariant(int[], long[]) loop_optimization (after)
320   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
321   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                       loop:none
322   /// CHECK-DAG: <<Get:j\d+>>   ArrayGet [{{l\d+}},<<I0>>]          loop:none
323   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<Get>>]            loop:none
324   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
325   //
326   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>,{{j\d+}}]         loop:none
327   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]                         loop:<<Loop:B\d+>> outer_loop:none
328   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
329   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Rep>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
330   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                        loop:<<Loop>>      outer_loop:none
331   //
332   /// CHECK-ELSE:
333   //
334   ///     CHECK-DAG: <<I4:i\d+>>    IntConstant 4                       loop:none
335   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>]        loop:none
336   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]               loop:<<Loop:B\d+>> outer_loop:none
337   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Rep>>] loop:<<Loop>>      outer_loop:none
338   ///     CHECK-DAG:                Add [<<Phi>>,<<I4>>]                loop:<<Loop>>      outer_loop:none
339   //
340   /// CHECK-FI:
intVectorLongInvariant(int[] x, long[] y)341   static void intVectorLongInvariant(int[] x, long[] y) {
342     for (int i = 0; i < 100; i++) {
343       x[i] = (int) y[0];
344     }
345   }
346 
347   /// CHECK-START: void Main.longCanBeDoneWithInt(int[], int[]) loop_optimization (before)
348   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                        loop:none
349   /// CHECK-DAG: <<I1:i\d+>>    IntConstant 1                        loop:none
350   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1                       loop:none
351   /// CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,<<Add:i\d+>>]            loop:<<Loop:B\d+>> outer_loop:none
352   /// CHECK-DAG: <<Get:i\d+>>   ArrayGet [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
353   /// CHECK-DAG: <<Cnv1:j\d+>>  TypeConversion [<<Get>>]             loop:<<Loop>>      outer_loop:none
354   /// CHECK-DAG: <<AddL:j\d+>>  Add [<<Cnv1>>,<<L1>>]                loop:<<Loop>>      outer_loop:none
355   /// CHECK-DAG: <<Cnv2:i\d+>>  TypeConversion [<<AddL>>]            loop:<<Loop>>      outer_loop:none
356   /// CHECK-DAG:                ArraySet [{{l\d+}},<<Phi>>,<<Cnv2>>] loop:<<Loop>>      outer_loop:none
357   /// CHECK-DAG: <<Add>>        Add [<<Phi>>,<<I1>>]                 loop:<<Loop>>      outer_loop:none
358   //
359   /// CHECK-START-{X86_64,ARM64}: void Main.longCanBeDoneWithInt(int[], int[]) loop_optimization (after)
360   /// CHECK-DAG: <<I0:i\d+>>    IntConstant 0                       loop:none
361   /// CHECK-DAG: <<L1:j\d+>>    LongConstant 1                      loop:none
362   /// CHECK-DAG: <<Cnv:i\d+>>   TypeConversion [<<L1>>]             loop:none
363   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
364   //
365   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>,{{j\d+}}]         loop:none
366   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]                         loop:<<Loop:B\d+>> outer_loop:none
367   ///     CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}]               loop:<<Loop>>      outer_loop:none
368   ///     CHECK-DAG: <<Load:d\d+>>  VecLoad [{{l\d+}},<<Phi>>,<<LoopP>>]          loop:<<Loop>>      outer_loop:none
369   ///     CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Rep>>,<<LoopP>>]           loop:<<Loop>>      outer_loop:none
370   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Add>>,<<LoopP>>] loop:<<Loop>>      outer_loop:none
371   ///     CHECK-DAG:                Add [<<Phi>>,{{i\d+}}]                        loop:<<Loop>>      outer_loop:none
372   //
373   /// CHECK-ELSE:
374   //
375   ///     CHECK-DAG: <<I4:i\d+>>    IntConstant 4                       loop:none
376   ///     CHECK-DAG: <<Rep:d\d+>>   VecReplicateScalar [<<Cnv>>]        loop:none
377   ///     CHECK-DAG: <<Phi:i\d+>>   Phi [<<I0>>,{{i\d+}}]               loop:<<Loop:B\d+>> outer_loop:none
378   ///     CHECK-DAG: <<Load:d\d+>>  VecLoad [{{l\d+}},<<Phi>>]          loop:<<Loop>>      outer_loop:none
379   ///     CHECK-DAG: <<Add:d\d+>>   VecAdd [<<Load>>,<<Rep>>]           loop:<<Loop>>      outer_loop:none
380   ///     CHECK-DAG:                VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>>      outer_loop:none
381   ///     CHECK-DAG:                Add [<<Phi>>,<<I4>>]                loop:<<Loop>>      outer_loop:none
382   //
383   /// CHECK-FI:
longCanBeDoneWithInt(int[] x, int[] y)384   static void longCanBeDoneWithInt(int[] x, int[] y) {
385     for (int i = 0; i < 100; i++) {
386       x[i] = (int) (y[i] + 1L);
387     }
388   }
389 
testUnroll()390   static void testUnroll() {
391     float[] x = new float[100];
392     float[] y = new float[100];
393     for (int i = 0; i < 100; i++) {
394       x[i] = 0.0f;
395       y[i] = 2.0f;
396     }
397     unroll(x, y);
398     for (int i = 0; i < 100; i++) {
399       expectEquals(5.0f, x[i]);
400       expectEquals(2.0f, y[i]);
401     }
402   }
403 
initArrayStencil(int[] arr)404   private static void initArrayStencil(int[] arr) {
405     for (int i = 0; i < arr.length; i++) {
406       arr[i] = i;
407     }
408   }
409 
testStencil1()410   static void testStencil1() {
411     int[] a = new int[100];
412     int[] b = new int[100];
413     initArrayStencil(b);
414 
415     stencil(a, b, 100);
416     for (int i = 1; i < 99; i++) {
417       int e = i + i + i;
418       expectEquals(e, a[i]);
419       expectEquals(i, b[i]);
420     }
421   }
422 
423   // Checks the disambiguation runtime test for array references.
testStencilConstSize()424   static void testStencilConstSize() {
425     int[] a = new int[STENCIL_ARRAY_SIZE];
426     int[] b = new int[STENCIL_ARRAY_SIZE];
427     initArrayStencil(b);
428 
429     for (int i = 1; i < STENCIL_ARRAY_SIZE - 1; i++) {
430     $noinline$stencilConstSize(a, b);
431       // (i - 1) + i + (i + 1) = 3 * i.
432       int e = i + i + i;
433       expectEquals(e, a[i]);
434       expectEquals(i, b[i]);
435     }
436 
437     initArrayStencil(b);
438     $noinline$stencilConstSize(b, b);
439 
440     for (int i = 1; i < STENCIL_ARRAY_SIZE - 1; i++) {
441       // The formula of the ith member of recurrent def: b[i] = b[i-1] + (i) + (i+1).
442       int e = i * (i + 2);
443       expectEquals(e, b[i]);
444     }
445   }
446 
testStencil2()447   static void testStencil2() {
448     int[] a = new int[100];
449     int[] b = new int[100];
450     initArrayStencil(b);
451 
452     stencilSubInt(a, b, 100);
453     for (int i = 1; i < 99; i++) {
454       int e = i + i + i;
455       expectEquals(e, a[i]);
456       expectEquals(i, b[i]);
457     }
458   }
459 
testStencil3()460   static void testStencil3() {
461     int[] a = new int[100];
462     int[] b = new int[100];
463     initArrayStencil(b);
464 
465     stencilAddInt(a, b, 100);
466     for (int i = 1; i < 99; i++) {
467       int e = i + i + i;
468       expectEquals(e, a[i]);
469       expectEquals(i, b[i]);
470     }
471   }
472 
testTypes()473   static void testTypes() {
474     int[] a = new int[100];
475     int[] b = new int[100];
476     long[] l = { 3 };
477     expectEquals(31, longInductionReduction(l));
478     intVectorLongInvariant(a, l);
479     for (int i = 0; i < 100; i++) {
480       expectEquals(3, a[i]);
481     }
482     longCanBeDoneWithInt(b, a);
483     for (int i = 0; i < 100; i++) {
484       expectEquals(4, b[i]);
485     }
486   }
487 
main(String[] args)488   public static void main(String[] args) {
489     testUnroll();
490     testStencil1();
491     testStencilConstSize();
492     testStencil2();
493     testStencil3();
494     testTypes();
495     System.out.println("passed");
496   }
497 
expectEquals(int expected, int result)498   private static void expectEquals(int expected, int result) {
499     if (expected != result) {
500       throw new Error("Expected: " + expected + ", found: " + result);
501     }
502   }
503 
expectEquals(long expected, long result)504   private static void expectEquals(long expected, long result) {
505     if (expected != result) {
506       throw new Error("Expected: " + expected + ", found: " + result);
507     }
508   }
509 
expectEquals(float expected, float result)510   private static void expectEquals(float expected, float result) {
511     if (expected != result) {
512       throw new Error("Expected: " + expected + ", found: " + result);
513     }
514   }
515 }
516