1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package other;
18 
19 /**
20  * Tests for dot product idiom vectorization.
21  */
22 public class TestVarious {
23 
24   /// CHECK-START: int other.TestVarious.testDotProdConstRight(byte[]) loop_optimization (before)
25   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
26   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
27   /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89                                        loop:none
28   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
29   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
30   /// CHECK-DAG: <<Get1:b\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
31   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<Const89>>]                            loop:<<Loop>>      outer_loop:none
32   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
33   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
34 
35   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdConstRight(byte[]) loop_optimization (after)
36   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
37   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
38   /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89                                        loop:none
39   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
40   //
41   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
42   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const89>>,{{j\d+}}]                       loop:none
43   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
44   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                          loop:<<Loop>>      outer_loop:none
45   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
46   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
47   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>,<<LoopP>>] type:Int8    loop:<<Loop>>      outer_loop:none
48   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
49   //
50   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>,{{j\d+}}]                                   loop:none
51   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>,{{j\d+}}]                          loop:none
52   //
53   /// CHECK-ELSE:
54   //
55   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
56   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
57   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const89>>]                      loop:none
58   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
59   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
60   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
61   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8    loop:<<Loop>>      outer_loop:none
62   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
63   //
64   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
65   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
66   //
67   /// CHECK-FI:
testDotProdConstRight(byte[] b)68   public static final int testDotProdConstRight(byte[] b) {
69     int s = 1;
70     for (int i = 0; i < b.length; i++) {
71       int temp =  b[i] * 89;
72       s += temp;
73     }
74     return s;
75   }
76 
77   /// CHECK-START: int other.TestVarious.testDotProdConstLeft(byte[]) loop_optimization (before)
78   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
79   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
80   /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89                                        loop:none
81   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
82   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
83   /// CHECK-DAG: <<Get1:a\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
84   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<Const89>>]                            loop:<<Loop>>      outer_loop:none
85   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
86   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
87 
88   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdConstLeft(byte[]) loop_optimization (after)
89   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
90   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
91   /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89                                        loop:none
92   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
93   //
94   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
95   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const89>>,{{j\d+}}]                       loop:none
96   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
97   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                          loop:<<Loop>>      outer_loop:none
98   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
99   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
100   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>,<<LoopP>>] type:Uint8   loop:<<Loop>>      outer_loop:none
101   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
102   //
103   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>,{{j\d+}}]                                   loop:none
104   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>,{{j\d+}}]                          loop:none
105   //
106   /// CHECK-ELSE:
107   //
108   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
109   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
110   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const89>>]                      loop:none
111   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
112   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
113   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
114   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Uint8   loop:<<Loop>>      outer_loop:none
115   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
116   //
117   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
118   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
119   //
120   /// CHECK-FI:
testDotProdConstLeft(byte[] b)121   public static final int testDotProdConstLeft(byte[] b) {
122     int s = 1;
123     for (int i = 0; i < b.length; i++) {
124       int temp = 89 * (b[i] & 0xff);
125       s += temp;
126     }
127     return s;
128   }
129 
130   /// CHECK-START: int other.TestVarious.testDotProdLoopInvariantConvRight(byte[], int) loop_optimization (before)
131   /// CHECK-DAG: <<Param:i\d+>>   ParameterValue                                        loop:none
132   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
133   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
134   /// CHECK-DAG: <<ConstL:i\d+>>  IntConstant 129                                       loop:none
135   /// CHECK-DAG: <<AddP:i\d+>>    Add [<<Param>>,<<ConstL>>]                            loop:none
136   /// CHECK-DAG: <<TypeCnv:b\d+>> TypeConversion [<<AddP>>]                             loop:none
137   //
138   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
139   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
140   /// CHECK-DAG: <<Get1:b\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
141   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<TypeCnv>>]                            loop:<<Loop>>      outer_loop:none
142   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
143   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
144 
145   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdLoopInvariantConvRight(byte[], int) loop_optimization (after)
146   /// CHECK-DAG: <<Param:i\d+>>   ParameterValue                                        loop:none
147   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
148   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
149   /// CHECK-DAG: <<ConstL:i\d+>>  IntConstant 129                                       loop:none
150   /// CHECK-DAG: <<AddP:i\d+>>    Add [<<Param>>,<<ConstL>>]                            loop:none
151   /// CHECK-DAG: <<TypeCnv:b\d+>> TypeConversion [<<AddP>>]                             loop:none
152   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
153   //
154   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
155   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<TypeCnv>>,{{j\d+}}]                       loop:none
156   //
157   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
158   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                          loop:<<Loop>>      outer_loop:none
159   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
160   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
161   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>,<<LoopP>>] type:Int8    loop:<<Loop>>      outer_loop:none
162   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
163   //
164   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>,{{j\d+}}]                                   loop:none
165   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>,{{j\d+}}]                          loop:none
166   //
167   /// CHECK-ELSE:
168   //
169   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
170   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
171   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<TypeCnv>>]                      loop:none
172   //
173   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
174   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
175   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
176   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8    loop:<<Loop>>      outer_loop:none
177   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
178   //
179   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
180   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
181   //
182   /// CHECK-FI:
testDotProdLoopInvariantConvRight(byte[] b, int param)183   public static final int testDotProdLoopInvariantConvRight(byte[] b, int param) {
184     int s = 1;
185     for (int i = 0; i < b.length; i++) {
186       int temp = b[i] * ((byte)(param + 129));
187       s += temp;
188     }
189     return s;
190   }
191 
192   /// CHECK-START: int other.TestVarious.testDotProdByteToChar(char[], char[]) loop_optimization (after)
193   /// CHECK-NOT:                  VecDotProd
testDotProdByteToChar(char[] a, char[] b)194   public static final int testDotProdByteToChar(char[] a, char[] b) {
195     int s = 1;
196     for (int i = 0; i < b.length; i++) {
197       int temp = ((char)((byte)(a[i] + 129))) * b[i];
198       s += temp;
199     }
200     return s;
201   }
202 
203   /// CHECK-START: int other.TestVarious.testDotProdMixedSize(byte[], short[]) loop_optimization (after)
204   /// CHECK-NOT:                  VecDotProd
testDotProdMixedSize(byte[] a, short[] b)205   public static final int testDotProdMixedSize(byte[] a, short[] b) {
206     int s = 1;
207     for (int i = 0; i < b.length; i++) {
208       int temp = a[i] * b[i];
209       s += temp;
210     }
211     return s;
212   }
213 
214   /// CHECK-START: int other.TestVarious.testDotProdMixedSizeAndSign(byte[], char[]) loop_optimization (after)
215   /// CHECK-NOT:                  VecDotProd
testDotProdMixedSizeAndSign(byte[] a, char[] b)216   public static final int testDotProdMixedSizeAndSign(byte[] a, char[] b) {
217     int s = 1;
218     for (int i = 0; i < b.length; i++) {
219       int temp = a[i] * b[i];
220       s += temp;
221     }
222     return s;
223   }
224 
225   /// CHECK-START: int other.TestVarious.testDotProdInt32(int[], int[]) loop_optimization (before)
226   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
227   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
228   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
229   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
230   /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
231   /// CHECK-DAG: <<Get2:i\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
232   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<Get2>>]                   loop:<<Loop>>      outer_loop:none
233   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                    loop:<<Loop>>      outer_loop:none
234   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
235 
236   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdInt32(int[], int[]) loop_optimization (after)
237   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
238   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
239   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
240   //
241   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>,{{j\d+}}]                 loop:none
242   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                           loop:<<Loop:B\d+>> outer_loop:none
243   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                              loop:<<Loop>>      outer_loop:none
244   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                    loop:<<Loop>>      outer_loop:none
245   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]               loop:<<Loop>>      outer_loop:none
246   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]               loop:<<Loop>>      outer_loop:none
247   ///     CHECK-DAG: <<Mul:d\d+>>     VecMul [<<Load1>>,<<Load2>>,<<LoopP>>]              loop:<<Loop>>      outer_loop:none
248   ///     CHECK-DAG:                  VecAdd [<<Phi2>>,<<Mul>>,<<LoopP>>]                 loop:<<Loop>>      outer_loop:none
249   //
250   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>,{{j\d+}}]                       loop:none
251   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>,{{j\d+}}]              loop:none
252   //
253   /// CHECK-ELSE:
254   //
255   ///     CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                loop:none
256   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
257   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                    loop:<<Loop>>      outer_loop:none
258   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]               loop:<<Loop>>      outer_loop:none
259   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]               loop:<<Loop>>      outer_loop:none
260   ///     CHECK-DAG: <<Mul:d\d+>>     VecMul [<<Load1>>,<<Load2>>]              loop:<<Loop>>      outer_loop:none
261   ///     CHECK-DAG:                  VecAdd [<<Phi2>>,<<Mul>>]                 loop:<<Loop>>      outer_loop:none
262   //
263   ///     CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                      loop:none
264   ///     CHECK-DAG:                  VecExtractScalar [<<Reduce>>]             loop:none
265   //
266   /// CHECK-FI:
testDotProdInt32(int[] a, int[] b)267   public static final int testDotProdInt32(int[] a, int[] b) {
268     int s = 1;
269     for (int i = 0;  i < b.length; i++) {
270       int temp = a[i] * b[i];
271       s += temp;
272     }
273     return s;
274   }
275 
276   /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsigned1(byte[], byte[]) loop_optimization (before)
277   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
278   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
279   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                             loop:none
280   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
281   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
282   /// CHECK-DAG: <<Phi3:i\d+>>    Phi [<<Const2>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
283   /// CHECK-DAG: <<Get1:b\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
284   /// CHECK-DAG: <<Get2:b\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
285   /// CHECK-DAG: <<Mul1:i\d+>>    Mul [<<Get1>>,<<Get2>>]                   loop:<<Loop>>      outer_loop:none
286   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul1>>]                   loop:<<Loop>>      outer_loop:none
287   /// CHECK-DAG: <<TypeC1:a\d+>>  TypeConversion [<<Get1>>]                 loop:<<Loop>>      outer_loop:none
288   /// CHECK-DAG: <<TypeC2:a\d+>>  TypeConversion [<<Get2>>]                 loop:<<Loop>>      outer_loop:none
289   /// CHECK-DAG: <<Mul2:i\d+>>    Mul [<<TypeC1>>,<<TypeC2>>]               loop:<<Loop>>      outer_loop:none
290   /// CHECK-DAG:                  Add [<<Phi3>>,<<Mul2>>]                   loop:<<Loop>>      outer_loop:none
291   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
292 
293   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsigned1(byte[], byte[]) loop_optimization (after)
294   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
295   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
296   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                                         loop:none
297   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
298   //
299   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
300   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>,{{j\d+}}]                             loop:none
301   //
302   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
303   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
304   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
305   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
306   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
307   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
308   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>,<<LoopP>>] type:Int8   loop:<<Loop>>      outer_loop:none
309   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load1>>,<<Load2>>,<<LoopP>>] type:Uint8  loop:<<Loop>>      outer_loop:none
310   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
311   //
312   /// CHECK-ELSE:
313   //
314   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
315   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>]                            loop:none
316   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>]                            loop:none
317   //
318   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
319   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
320   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
321   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
322   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
323   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int8   loop:<<Loop>>      outer_loop:none
324   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load1>>,<<Load2>>] type:Uint8  loop:<<Loop>>      outer_loop:none
325   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
326   //
327   /// CHECK-FI:
testDotProdBothSignedUnsigned1(byte[] a, byte[] b)328   public static final int testDotProdBothSignedUnsigned1(byte[] a, byte[] b) {
329     int s1 = 1;
330     int s2 = 2;
331     for (int i = 0; i < b.length; i++) {
332       byte a_val = a[i];
333       byte b_val = b[i];
334       s1 += a_val * b_val;
335       s2 += (a_val & 0xff) * (b_val & 0xff);
336     }
337     return s1 + s2;
338   }
339 
340   /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsigned2(byte[], byte[]) loop_optimization (before)
341   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
342   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
343   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                             loop:none
344   /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42                            loop:none
345   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
346   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
347   /// CHECK-DAG: <<Phi3:i\d+>>    Phi [<<Const2>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
348   /// CHECK-DAG: <<Get1:b\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
349   /// CHECK-DAG: <<Get2:a\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
350   /// CHECK-DAG: <<TypeC1:a\d+>>  TypeConversion [<<Get1>>]                 loop:<<Loop>>      outer_loop:none
351   /// CHECK-DAG: <<Mul1:i\d+>>    Mul [<<Get2>>,<<TypeC1>>]                 loop:<<Loop>>      outer_loop:none
352   /// CHECK-DAG:                  Add [<<Phi3>>,<<Mul1>>]                   loop:<<Loop>>      outer_loop:none
353   /// CHECK-DAG: <<Mul2:i\d+>>    Mul [<<Get1>>,<<Const42>>]                loop:<<Loop>>      outer_loop:none
354   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul2>>]                   loop:<<Loop>>      outer_loop:none
355   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
356 
357   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsigned2(byte[], byte[]) loop_optimization (after)
358   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
359   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
360   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                                         loop:none
361   /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42                                        loop:none
362   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
363   //
364   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const42>>,{{j\d+}}]                       loop:none
365   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
366   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>,{{j\d+}}]                             loop:none
367   //
368   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
369   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
370   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
371   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
372   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
373   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
374   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load2>>,<<Load1>>,<<LoopP>>] type:Uint8  loop:<<Loop>>      outer_loop:none
375   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>,<<LoopP>>] type:Int8    loop:<<Loop>>      outer_loop:none
376   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
377   //
378   /// CHECK-ELSE:
379   //
380   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
381   ///     CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const42>>]                      loop:none
382   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>]                            loop:none
383   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>]                            loop:none
384   //
385   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
386   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
387   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
388   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
389   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
390   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load2>>,<<Load1>>] type:Uint8  loop:<<Loop>>      outer_loop:none
391   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8    loop:<<Loop>>      outer_loop:none
392   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
393   //
394   /// CHECK-FI:
testDotProdBothSignedUnsigned2(byte[] a, byte[] b)395   public static final int testDotProdBothSignedUnsigned2(byte[] a, byte[] b) {
396     int s1 = 1;
397     int s2 = 2;
398     for (int i = 0; i < b.length; i++) {
399       byte a_val = a[i];
400       byte b_val = b[i];
401       s2 += (a_val & 0xff) * (b_val & 0xff);
402       s1 += a_val * 42;
403     }
404     return s1 + s2;
405   }
406 
407   /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsignedDoubleLoad(byte[], byte[]) loop_optimization (before)
408   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
409   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
410   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                             loop:none
411   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
412   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
413   /// CHECK-DAG: <<Phi3:i\d+>>    Phi [<<Const2>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
414   /// CHECK-DAG: <<GetB1:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
415   /// CHECK-DAG: <<GetB2:b\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
416   /// CHECK-DAG: <<Mul1:i\d+>>    Mul [<<GetB1>>,<<GetB2>>]                 loop:<<Loop>>      outer_loop:none
417   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul1>>]                   loop:<<Loop>>      outer_loop:none
418   /// CHECK-DAG: <<GetA1:a\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
419   /// CHECK-DAG: <<GetA2:a\d+>>   ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
420   /// CHECK-DAG: <<Mul2:i\d+>>    Mul [<<GetA1>>,<<GetA2>>]                 loop:<<Loop>>      outer_loop:none
421   /// CHECK-DAG:                  Add [<<Phi3>>,<<Mul2>>]                   loop:<<Loop>>      outer_loop:none
422   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
423 
424   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsignedDoubleLoad(byte[], byte[]) loop_optimization (after)
425   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
426   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
427   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                                         loop:none
428   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
429   //
430   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>,{{j\d+}}]                             loop:none
431   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>,{{j\d+}}]                             loop:none
432   //
433   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                                       loop:<<Loop:B\d+>> outer_loop:none
434   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
435   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                                         loop:<<Loop>>      outer_loop:none
436   ///     CHECK-DAG: <<LoopP:j\d+>>   VecPredWhile [<<Phi1>>,{{i\d+}}]                                loop:<<Loop>>      outer_loop:none
437   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
438   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
439   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>,<<LoopP>>] type:Int8   loop:<<Loop>>      outer_loop:none
440   ///     CHECK-DAG: <<Load3:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
441   ///     CHECK-DAG: <<Load4:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>,<<LoopP>>]                           loop:<<Loop>>      outer_loop:none
442   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load3>>,<<Load4>>,<<LoopP>>] type:Uint8  loop:<<Loop>>      outer_loop:none
443   ///     CHECK-DAG:                  Add [<<Phi1>>,{{i\d+}}]                                         loop:<<Loop>>      outer_loop:none
444   //
445   /// CHECK-ELSE:
446   //
447   ///     CHECK-DAG: <<Const16:i\d+>> IntConstant 16                                        loop:none
448   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>]                            loop:none
449   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>]                            loop:none
450   //
451   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
452   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
453   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
454   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
455   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
456   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int8   loop:<<Loop>>      outer_loop:none
457   ///     CHECK-DAG: <<Load3:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
458   ///     CHECK-DAG: <<Load4:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
459   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load3>>,<<Load4>>] type:Uint8  loop:<<Loop>>      outer_loop:none
460   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const16>>]                            loop:<<Loop>>      outer_loop:none
461   //
462   /// CHECK-FI:
testDotProdBothSignedUnsignedDoubleLoad(byte[] a, byte[] b)463   public static final int testDotProdBothSignedUnsignedDoubleLoad(byte[] a, byte[] b) {
464     int s1 = 1;
465     int s2 = 2;
466     for (int i = 0; i < b.length; i++) {
467       s1 += a[i] * b[i];
468       s2 += (a[i] & 0xff) * (b[i] & 0xff);
469     }
470     return s1 + s2;
471   }
472 
473   /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsignedChar(char[], char[]) loop_optimization (before)
474   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
475   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
476   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                             loop:none
477   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
478   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
479   /// CHECK-DAG: <<Phi3:i\d+>>    Phi [<<Const2>>,{{i\d+}}]                 loop:<<Loop>>      outer_loop:none
480   /// CHECK-DAG: <<Get1:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
481   /// CHECK-DAG: <<Get2:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]              loop:<<Loop>>      outer_loop:none
482   /// CHECK-DAG: <<TypeS1:s\d+>>  TypeConversion [<<Get1>>]                 loop:<<Loop>>      outer_loop:none
483   /// CHECK-DAG: <<TypeS2:s\d+>>  TypeConversion [<<Get2>>]                 loop:<<Loop>>      outer_loop:none
484   /// CHECK-DAG: <<Mul1:i\d+>>    Mul [<<TypeS1>>,<<TypeS2>>]               loop:<<Loop>>      outer_loop:none
485   /// CHECK-DAG:                  Add [<<Phi3>>,<<Mul1>>]                   loop:<<Loop>>      outer_loop:none
486   /// CHECK-DAG: <<Mul2:i\d+>>    Mul [<<Get1>>,<<Get2>>]                   loop:<<Loop>>      outer_loop:none
487   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul2>>]                   loop:<<Loop>>      outer_loop:none
488   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
489 
490   /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsignedChar(char[], char[]) loop_optimization (after)
491   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
492   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
493   /// CHECK-DAG: <<Const2:i\d+>>  IntConstant 2                                         loop:none
494   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
495   //
496   //      16-bit DotProd is not supported for SVE.
497   ///     CHECK-NOT:                  VecDotProd
498   //
499   /// CHECK-ELSE:
500   //
501   ///     CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
502   ///     CHECK-DAG: <<Set1:d\d+>>    VecSetScalars [<<Const1>>]                            loop:none
503   ///     CHECK-DAG: <<Set2:d\d+>>    VecSetScalars [<<Const2>>]                            loop:none
504   //
505   ///     CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
506   ///     CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set1>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
507   ///     CHECK-DAG: <<Phi3:d\d+>>    Phi [<<Set2>>,{{d\d+}}]                               loop:<<Loop>>      outer_loop:none
508   ///     CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
509   ///     CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
510   ///     CHECK-DAG:                  VecDotProd [<<Phi3>>,<<Load1>>,<<Load2>>] type:Int16  loop:<<Loop>>      outer_loop:none
511   ///     CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Uint16 loop:<<Loop>>      outer_loop:none
512   ///     CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
513   //
514   /// CHECK-FI:
testDotProdBothSignedUnsignedChar(char[] a, char[] b)515   public static final int testDotProdBothSignedUnsignedChar(char[] a, char[] b) {
516     int s1 = 1;
517     int s2 = 2;
518     for (int i = 0; i < b.length; i++) {
519       char a_val = a[i];
520       char b_val = b[i];
521       s2 += ((short)a_val) * ((short)b_val);
522       s1 += a_val * b_val;
523     }
524     return s1 + s2;
525   }
526 
expectEquals(int expected, int result)527   private static void expectEquals(int expected, int result) {
528     if (expected != result) {
529       throw new Error("Expected: " + expected + ", found: " + result);
530     }
531   }
532 
run()533   public static void run() {
534     final short MAX_S = Short.MAX_VALUE;
535     final short MIN_S = Short.MAX_VALUE;
536 
537     byte[] b1 = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128 };
538     byte[] b2 = {  127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  127,  127,  127,  127 };
539 
540     char[] c1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
541     char[] c2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
542 
543     int[] i1 = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128 };
544     int[] i2 = {  127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  127,  127,  127,  127 };
545 
546     short[] s1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
547 
548     expectEquals(56516, testDotProdConstRight(b2));
549     expectEquals(56516, testDotProdConstLeft(b2));
550     expectEquals(1271, testDotProdLoopInvariantConvRight(b2, 129));
551     expectEquals(-8519423, testDotProdByteToChar(c1, c2));
552     expectEquals(-8388351, testDotProdMixedSize(b1, s1));
553     expectEquals(-8388351, testDotProdMixedSizeAndSign(b1, c2));
554     expectEquals(-81279, testDotProdInt32(i1, i2));
555     expectEquals(3, testDotProdBothSignedUnsigned1(b1, b2));
556     expectEquals(54403, testDotProdBothSignedUnsigned2(b1, b2));
557     expectEquals(3, testDotProdBothSignedUnsignedDoubleLoad(b1, b2));
558     expectEquals(-262137, testDotProdBothSignedUnsignedChar(c1, c2));
559   }
560 
main(String[] args)561   public static void main(String[] args) {
562     run();
563   }
564 }
565