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: char and short case.
21  */
22 public class TestCharShort {
23 
24   public static final int ARRAY_SIZE = 1024;
25 
26   /// CHECK-START: int other.TestCharShort.testDotProdSimple(short[], short[]) loop_optimization (before)
27   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
28   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
29   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
30   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
31   /// CHECK-DAG: <<Get1:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
32   /// CHECK-DAG: <<Get2:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
33   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<Get2>>]                               loop:<<Loop>>      outer_loop:none
34   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
35   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
36 
37   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSimple(short[], short[]) loop_optimization (after)
38   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
39   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
40   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
41   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
42   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
43   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
44   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
45   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
46   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int16  loop:<<Loop>>      outer_loop:none
47   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
48   //
49   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
50   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdSimple(short[] a, short[] b)51   public static final int testDotProdSimple(short[] a, short[] b) {
52     int s = 1;
53     for (int i = 0; i < b.length; i++) {
54       int temp = a[i] * b[i];
55       s += temp;
56     }
57     return s - 1;
58   }
59 
60   /// CHECK-START: int other.TestCharShort.testDotProdComplex(short[], short[]) loop_optimization (before)
61   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
62   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
63   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
64   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
65   /// CHECK-DAG: <<Get1:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
66   /// CHECK-DAG: <<AddC1:i\d+>>   Add [<<Get1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
67   /// CHECK-DAG: <<TypeC1:s\d+>>  TypeConversion [<<AddC1>>]                            loop:<<Loop>>      outer_loop:none
68   /// CHECK-DAG: <<Get2:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
69   /// CHECK-DAG: <<AddC2:i\d+>>   Add [<<Get2>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
70   /// CHECK-DAG: <<TypeC2:s\d+>>  TypeConversion [<<AddC2>>]                            loop:<<Loop>>      outer_loop:none
71   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<TypeC1>>,<<TypeC2>>]                           loop:<<Loop>>      outer_loop:none
72   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
73   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
74 
75   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplex(short[], short[]) loop_optimization (after)
76   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
77   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
78   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
79   /// CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const1>>]                       loop:none
80   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
81   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
82   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
83   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
84   /// CHECK-DAG: <<VAdd1:d\d+>>   VecAdd [<<Load1>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
85   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
86   /// CHECK-DAG: <<VAdd2:d\d+>>   VecAdd [<<Load2>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
87   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Int16  loop:<<Loop>>      outer_loop:none
88   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
89   //
90   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
91   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdComplex(short[] a, short[] b)92   public static final int testDotProdComplex(short[] a, short[] b) {
93     int s = 1;
94     for (int i = 0; i < b.length; i++) {
95       int temp = ((short)(a[i] + 1)) * ((short)(b[i] + 1));
96       s += temp;
97     }
98     return s - 1;
99   }
100 
101   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsigned(char[], char[]) loop_optimization (before)
102   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
103   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
104   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
105   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
106   /// CHECK-DAG: <<Get1:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
107   /// CHECK-DAG: <<Get2:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
108   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<Get1>>,<<Get2>>]                               loop:<<Loop>>      outer_loop:none
109   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
110   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
111 
112   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSimpleUnsigned(char[], char[]) loop_optimization (after)
113   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
114   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
115   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
116   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
117   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
118   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
119   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
120   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
121   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Uint16 loop:<<Loop>>      outer_loop:none
122   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
123   //
124   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
125   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdSimpleUnsigned(char[] a, char[] b)126   public static final int testDotProdSimpleUnsigned(char[] a, char[] b) {
127     int s = 1;
128     for (int i = 0; i < b.length; i++) {
129       int temp = a[i] * b[i];
130       s += temp;
131     }
132     return s - 1;
133   }
134 
135   /// CHECK-START: int other.TestCharShort.testDotProdComplexUnsigned(char[], char[]) loop_optimization (before)
136   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
137   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
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:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
141   /// CHECK-DAG: <<AddC:i\d+>>    Add [<<Get1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
142   /// CHECK-DAG: <<TypeC1:c\d+>>  TypeConversion [<<AddC>>]                             loop:<<Loop>>      outer_loop:none
143   /// CHECK-DAG: <<Get2:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
144   /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
145   /// CHECK-DAG: <<TypeC2:c\d+>>  TypeConversion [<<AddGets>>]                          loop:<<Loop>>      outer_loop:none
146   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<TypeC1>>,<<TypeC2>>]                           loop:<<Loop>>      outer_loop:none
147   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
148   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
149 
150   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexUnsigned(char[], char[]) loop_optimization (after)
151   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
152   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
153   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
154   /// CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const1>>]                       loop:none
155   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
156   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
157   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
158   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
159   /// CHECK-DAG: <<VAdd1:d\d+>>   VecAdd [<<Load1>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
160   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
161   /// CHECK-DAG: <<VAdd2:d\d+>>   VecAdd [<<Load2>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
162   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Uint16 loop:<<Loop>>      outer_loop:none
163   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
164   //
165   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
166   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdComplexUnsigned(char[] a, char[] b)167   public static final int testDotProdComplexUnsigned(char[] a, char[] b) {
168     int s = 1;
169     for (int i = 0; i < b.length; i++) {
170       int temp = ((char)(a[i] + 1)) * ((char)(b[i] + 1));
171       s += temp;
172     }
173     return s - 1;
174   }
175 
176   /// CHECK-START: int other.TestCharShort.testDotProdComplexUnsignedCastedToSigned(char[], char[]) loop_optimization (before)
177   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
178   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
179   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
180   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
181   /// CHECK-DAG: <<Get1:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
182   /// CHECK-DAG: <<AddC:i\d+>>    Add [<<Get1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
183   /// CHECK-DAG: <<TypeC1:s\d+>>  TypeConversion [<<AddC>>]                             loop:<<Loop>>      outer_loop:none
184   /// CHECK-DAG: <<Get2:c\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
185   /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
186   /// CHECK-DAG: <<TypeC2:s\d+>>  TypeConversion [<<AddGets>>]                          loop:<<Loop>>      outer_loop:none
187   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<TypeC1>>,<<TypeC2>>]                           loop:<<Loop>>      outer_loop:none
188   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
189   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
190 
191   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexUnsignedCastedToSigned(char[], char[]) loop_optimization (after)
192   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
193   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
194   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
195   /// CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const1>>]                       loop:none
196   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
197   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
198   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
199   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
200   /// CHECK-DAG: <<VAdd1:d\d+>>   VecAdd [<<Load1>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
201   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
202   /// CHECK-DAG: <<VAdd2:d\d+>>   VecAdd [<<Load2>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
203   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Int16  loop:<<Loop>>      outer_loop:none
204   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
205   //
206   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
207   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdComplexUnsignedCastedToSigned(char[] a, char[] b)208   public static final int testDotProdComplexUnsignedCastedToSigned(char[] a, char[] b) {
209     int s = 1;
210     for (int i = 0; i < b.length; i++) {
211       int temp = ((short)(a[i] + 1)) * ((short)(b[i] + 1));
212       s += temp;
213     }
214     return s - 1;
215   }
216 
217   /// CHECK-START: int other.TestCharShort.testDotProdComplexSignedCastedToUnsigned(short[], short[]) loop_optimization (before)
218   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
219   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
220   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
221   /// CHECK-DAG: <<Phi2:i\d+>>    Phi [<<Const1>>,{{i\d+}}]                             loop:<<Loop>>      outer_loop:none
222   /// CHECK-DAG: <<Get1:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
223   /// CHECK-DAG: <<AddC:i\d+>>    Add [<<Get1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
224   /// CHECK-DAG: <<TypeC1:c\d+>>  TypeConversion [<<AddC>>]                             loop:<<Loop>>      outer_loop:none
225   /// CHECK-DAG: <<Get2:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]                          loop:<<Loop>>      outer_loop:none
226   /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
227   /// CHECK-DAG: <<TypeC2:c\d+>>  TypeConversion [<<AddGets>>]                          loop:<<Loop>>      outer_loop:none
228   /// CHECK-DAG: <<Mul:i\d+>>     Mul [<<TypeC1>>,<<TypeC2>>]                           loop:<<Loop>>      outer_loop:none
229   /// CHECK-DAG:                  Add [<<Phi2>>,<<Mul>>]                                loop:<<Loop>>      outer_loop:none
230   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const1>>]                             loop:<<Loop>>      outer_loop:none
231 
232   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexSignedCastedToUnsigned(short[], short[]) loop_optimization (after)
233   /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                                         loop:none
234   /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                                         loop:none
235   /// CHECK-DAG: <<Const8:i\d+>>  IntConstant 8                                         loop:none
236   /// CHECK-DAG: <<Repl:d\d+>>    VecReplicateScalar [<<Const1>>]                       loop:none
237   /// CHECK-DAG: <<Set:d\d+>>     VecSetScalars [<<Const1>>]                            loop:none
238   /// CHECK-DAG: <<Phi1:i\d+>>    Phi [<<Const0>>,{{i\d+}}]                             loop:<<Loop:B\d+>> outer_loop:none
239   /// CHECK-DAG: <<Phi2:d\d+>>    Phi [<<Set>>,{{d\d+}}]                                loop:<<Loop>>      outer_loop:none
240   /// CHECK-DAG: <<Load1:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
241   /// CHECK-DAG: <<VAdd1:d\d+>>   VecAdd [<<Load1>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
242   /// CHECK-DAG: <<Load2:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]                           loop:<<Loop>>      outer_loop:none
243   /// CHECK-DAG: <<VAdd2:d\d+>>   VecAdd [<<Load2>>,<<Repl>>]                           loop:<<Loop>>      outer_loop:none
244   /// CHECK-DAG:                  VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Uint16 loop:<<Loop>>      outer_loop:none
245   /// CHECK-DAG:                  Add [<<Phi1>>,<<Const8>>]                             loop:<<Loop>>      outer_loop:none
246   //
247   /// CHECK-DAG: <<Reduce:d\d+>>  VecReduce [<<Phi2>>]                                  loop:none
248   /// CHECK-DAG:                  VecExtractScalar [<<Reduce>>]                         loop:none
testDotProdComplexSignedCastedToUnsigned(short[] a, short[] b)249   public static final int testDotProdComplexSignedCastedToUnsigned(short[] a, short[] b) {
250     int s = 1;
251     for (int i = 0; i < b.length; i++) {
252       int temp = ((char)(a[i] + 1)) * ((char)(b[i] + 1));
253       s += temp;
254     }
255     return s - 1;
256   }
257 
258   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSignedToInt(short[], short[]) loop_optimization (after)
259   /// CHECK-DAG:                  VecDotProd type:Int16
testDotProdSignedToInt(short[] a, short[] b)260   public static final int testDotProdSignedToInt(short[] a, short[] b) {
261     int s = 1;
262     for (int i = 0; i < b.length; i++) {
263       int temp = ((int)(a[i])) * ((int)(b[i]));
264       s += temp;
265     }
266     return s - 1;
267   }
268 
269   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdParamSigned(int, short[]) loop_optimization (after)
270   /// CHECK-DAG:                  VecDotProd type:Int16
testDotProdParamSigned(int x, short[] b)271   public static final int testDotProdParamSigned(int x, short[] b) {
272     int s = 1;
273     for (int i = 0; i < b.length; i++) {
274       int temp = (short)(x) * b[i];
275       s += temp;
276     }
277     return s - 1;
278   }
279 
280   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdParamUnsigned(int, char[]) loop_optimization (after)
281   /// CHECK-DAG:                  VecDotProd type:Uint16
testDotProdParamUnsigned(int x, char[] b)282   public static final int testDotProdParamUnsigned(int x, char[] b) {
283     int s = 1;
284     for (int i = 0; i < b.length; i++) {
285       int temp = (char)(x) * b[i];
286       s += temp;
287     }
288     return s - 1;
289   }
290 
291   /// CHECK-START: int other.TestCharShort.testDotProdIntParam(int, short[]) loop_optimization (after)
292   /// CHECK-NOT:                  VecDotProd
testDotProdIntParam(int x, short[] b)293   public static final int testDotProdIntParam(int x, short[] b) {
294     int s = 1;
295     for (int i = 0; i < b.length; i++) {
296       int temp = b[i] * (x);
297       s += temp;
298     }
299     return s - 1;
300   }
301 
302   /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSignedToChar(short[], short[]) loop_optimization (after)
303   /// CHECK-DAG:                  VecDotProd type:Uint16
testDotProdSignedToChar(short[] a, short[] b)304   public static final int testDotProdSignedToChar(short[] a, short[] b) {
305     int s = 1;
306     for (int i = 0; i < b.length; i++) {
307       int temp = ((char)(a[i])) * ((char)(b[i]));
308       s += temp;
309     }
310     return s - 1;
311   }
312 
313   // Cases when result of Mul is type-converted are not supported.
314 
315   /// CHECK-START: int other.TestCharShort.testDotProdSimpleMulCastedToSigned(short[], short[]) loop_optimization (after)
316   /// CHECK-NOT:                  VecDotProd type:Uint16
testDotProdSimpleMulCastedToSigned(short[] a, short[] b)317   public static final int testDotProdSimpleMulCastedToSigned(short[] a, short[] b) {
318     int s = 1;
319     for (int i = 0; i < b.length; i++) {
320       short temp = (short)(a[i] * b[i]);
321       s += temp;
322     }
323     return s - 1;
324   }
325 
326 
327   /// CHECK-START: int other.TestCharShort.testDotProdSimpleMulCastedToUnsigned(short[], short[]) loop_optimization (after)
328   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleMulCastedToUnsigned(short[] a, short[] b)329   public static final int testDotProdSimpleMulCastedToUnsigned(short[] a, short[] b) {
330     int s = 1;
331     for (int i = 0; i < b.length; i++) {
332       char temp = (char)(a[i] * b[i]);
333       s += temp;
334     }
335     return s - 1;
336   }
337 
338   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedMulCastedToSigned(char[], char[]) loop_optimization (after)
339   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleUnsignedMulCastedToSigned(char[] a, char[] b)340   public static final int testDotProdSimpleUnsignedMulCastedToSigned(char[] a, char[] b) {
341     int s = 1;
342     for (int i = 0; i < b.length; i++) {
343       short temp = (short)(a[i] * b[i]);
344       s += temp;
345     }
346     return s - 1;
347   }
348 
349   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedMulCastedToUnsigned(char[], char[]) loop_optimization (after)
350   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleUnsignedMulCastedToUnsigned(char[] a, char[] b)351   public static final int testDotProdSimpleUnsignedMulCastedToUnsigned(char[] a, char[] b) {
352     int s = 1;
353     for (int i = 0; i < b.length; i++) {
354       char temp = (char)(a[i] * b[i]);
355       s += temp;
356     }
357     return s - 1;
358   }
359 
360   /// CHECK-START: int other.TestCharShort.testDotProdSimpleCastedToShort(short[], short[]) loop_optimization (after)
361   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleCastedToShort(short[] a, short[] b)362   public static final int testDotProdSimpleCastedToShort(short[] a, short[] b) {
363     int s = 1;
364     for (int i = 0; i < b.length; i++) {
365       short temp = (short)(a[i] * b[i]);
366       s += temp;
367     }
368     return s - 1;
369   }
370 
371   /// CHECK-START: int other.TestCharShort.testDotProdSimpleCastedToChar(short[], short[]) loop_optimization (after)
372   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleCastedToChar(short[] a, short[] b)373   public static final int testDotProdSimpleCastedToChar(short[] a, short[] b) {
374     int s = 1;
375     for (int i = 0; i < b.length; i++) {
376       char temp = (char)(a[i] * b[i]);
377       s += temp;
378     }
379     return s - 1;
380   }
381 
382   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToShort(char[], char[]) loop_optimization (after)
383   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleUnsignedCastedToShort(char[] a, char[] b)384   public static final int testDotProdSimpleUnsignedCastedToShort(char[] a, char[] b) {
385     int s = 1;
386     for (int i = 0; i < b.length; i++) {
387       short temp = (short)(a[i] * b[i]);
388       s += temp;
389     }
390     return s - 1;
391   }
392 
393   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToChar(char[], char[]) loop_optimization (after)
394   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleUnsignedCastedToChar(char[] a, char[] b)395   public static final int testDotProdSimpleUnsignedCastedToChar(char[] a, char[] b) {
396     int s = 1;
397     for (int i = 0; i < b.length; i++) {
398       char temp = (char)(a[i] * b[i]);
399       s += temp;
400     }
401     return s - 1;
402   }
403 
404   /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToLong(char[], char[]) loop_optimization (after)
405   /// CHECK-NOT:                  VecDotProd
testDotProdSimpleUnsignedCastedToLong(char[] a, char[] b)406   public static final int testDotProdSimpleUnsignedCastedToLong(char[] a, char[] b) {
407     int s = 1;
408     for (int i = 0; i < b.length; i++) {
409       long temp = (long)(a[i] * b[i]);
410       s += temp;
411     }
412     return s - 1;
413   }
414 
415   // Narrowing conversions.
416 
417   /// CHECK-START: int other.TestCharShort.testDotProdSignedNarrowerSigned(short[], short[]) loop_optimization (after)
418   /// CHECK-NOT:                  VecDotProd
testDotProdSignedNarrowerSigned(short[] a, short[] b)419   public static final int testDotProdSignedNarrowerSigned(short[] a, short[] b) {
420     int s = 1;
421     for (int i = 0; i < b.length; i++) {
422       int temp = ((byte)(a[i])) * ((byte)(b[i]));
423       s += temp;
424     }
425     return s - 1;
426   }
427 
428   /// CHECK-START: int other.TestCharShort.testDotProdSignedNarrowerUnsigned(short[], short[]) loop_optimization (after)
429   /// CHECK-NOT:                  VecDotProd
testDotProdSignedNarrowerUnsigned(short[] a, short[] b)430   public static final int testDotProdSignedNarrowerUnsigned(short[] a, short[] b) {
431     int s = 1;
432     for (int i = 0; i < b.length; i++) {
433       int temp = (a[i] & 0xff) * (b[i] & 0xff);
434       s += temp;
435     }
436     return s - 1;
437   }
438 
439   /// CHECK-START: int other.TestCharShort.testDotProdUnsignedNarrowerSigned(char[], char[]) loop_optimization (after)
440   /// CHECK-NOT:                  VecDotProd
testDotProdUnsignedNarrowerSigned(char[] a, char[] b)441   public static final int testDotProdUnsignedNarrowerSigned(char[] a, char[] b) {
442     int s = 1;
443     for (int i = 0; i < b.length; i++) {
444       int temp = ((byte)(a[i])) * ((byte)(b[i]));
445       s += temp;
446     }
447     return s - 1;
448   }
449 
450   /// CHECK-START: int other.TestCharShort.testDotProdUnsignedNarrowerUnsigned(char[], char[]) loop_optimization (after)
451   /// CHECK-NOT:                  VecDotProd
testDotProdUnsignedNarrowerUnsigned(char[] a, char[] b)452   public static final int testDotProdUnsignedNarrowerUnsigned(char[] a, char[] b) {
453     int s = 1;
454     for (int i = 0; i < b.length; i++) {
455       int temp = (a[i] & 0xff) * (b[i] & 0xff);
456       s += temp;
457     }
458     return s - 1;
459   }
460 
461   /// CHECK-START: int other.TestCharShort.testDotProdUnsignedSigned(char[], short[]) loop_optimization (after)
462   /// CHECK-NOT:                  VecDotProd
testDotProdUnsignedSigned(char[] a, short[] b)463   public static final int testDotProdUnsignedSigned(char[] a, short[] b) {
464     int s = 1;
465     for (int i = 0; i < b.length; i++) {
466       int temp = a[i] * b[i];
467       s += temp;
468     }
469     return s - 1;
470   }
471 
expectEquals(int expected, int result)472   private static void expectEquals(int expected, int result) {
473     if (expected != result) {
474       throw new Error("Expected: " + expected + ", found: " + result);
475     }
476   }
477 
testDotProd(short[] s1, short[] s2, char[] c1, char[] c2, int[] results)478   private static void testDotProd(short[] s1, short[] s2, char[] c1, char[] c2, int[] results) {
479     expectEquals(results[0], testDotProdSimple(s1, s2));
480     expectEquals(results[1], testDotProdComplex(s1, s2));
481     expectEquals(results[2], testDotProdSimpleUnsigned(c1, c2));
482     expectEquals(results[3], testDotProdComplexUnsigned(c1, c2));
483     expectEquals(results[4], testDotProdComplexUnsignedCastedToSigned(c1, c2));
484     expectEquals(results[5], testDotProdComplexSignedCastedToUnsigned(s1, s2));
485     expectEquals(results[6], testDotProdSignedToInt(s1, s2));
486     expectEquals(results[7], testDotProdParamSigned(-32768, s2));
487     expectEquals(results[8], testDotProdParamUnsigned(-32768, c2));
488     expectEquals(results[9], testDotProdIntParam(-32768, s2));
489     expectEquals(results[10], testDotProdSignedToChar(s1, s2));
490     expectEquals(results[11], testDotProdSimpleMulCastedToSigned(s1, s2));
491     expectEquals(results[12], testDotProdSimpleMulCastedToUnsigned(s1, s2));
492     expectEquals(results[13], testDotProdSimpleUnsignedMulCastedToSigned(c1, c2));
493     expectEquals(results[14], testDotProdSimpleUnsignedMulCastedToUnsigned(c1, c2));
494     expectEquals(results[15], testDotProdSimpleCastedToShort(s1, s2));
495     expectEquals(results[16], testDotProdSimpleCastedToChar(s1, s2));
496     expectEquals(results[17], testDotProdSimpleUnsignedCastedToShort(c1, c2));
497     expectEquals(results[18], testDotProdSimpleUnsignedCastedToChar(c1, c2));
498     expectEquals(results[19], testDotProdSimpleUnsignedCastedToLong(c1, c2));
499     expectEquals(results[20], testDotProdSignedNarrowerSigned(s1, s2));
500     expectEquals(results[21], testDotProdSignedNarrowerUnsigned(s1, s2));
501     expectEquals(results[22], testDotProdUnsignedNarrowerSigned(c1, c2));
502     expectEquals(results[23], testDotProdUnsignedNarrowerUnsigned(c1, c2));
503     expectEquals(results[24], testDotProdUnsignedSigned(c1, s2));
504   }
505 
run()506   public static void run() {
507     final short MAX_S = Short.MAX_VALUE;
508     final short MIN_S = Short.MAX_VALUE;
509 
510     short[] s1_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
511     short[] s2_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
512     char[]  c1_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
513     char[]  c2_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
514     int[] results_1 = { 2147352578, -2147483634, 2147352578, -2147483634, -2147483634, -2147483634,
515                         2147352578, -2147418112, 2147418112, -2147418112, 2147352578,
516                         2, 2, 2, 2, 2, 2, 2, 2, 2147352578, 2, 130050, 2, 130050, 2147352578 };
517     testDotProd(s1_1, s2_1, c1_1, c2_1, results_1);
518 
519     short[] s1_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S };
520     short[] s2_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S };
521     char[]  c1_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S };
522     char[]  c2_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S };
523     int[] results_2 = { -262140, 12, -262140, 12, 12, 12, -262140, 131072, -131072, 131072,
524                         -262140, 4, 4, 4, 4, 4, 4, 4, 4, -262140, 4, 260100, 4, 260100, -262140 };
525     testDotProd(s1_2, s2_2, c1_2, c2_2, results_2);
526 
527     short[] s1_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
528     short[] s2_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
529     char[]  c1_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
530     char[]  c2_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S };
531     int[] results_3 = { 2147352578, -2147483634, 2147352578, -2147483634, -2147483634,
532                         -2147483634, 2147352578, -2147418112, 2147418112, -2147418112,
533                         2147352578, 2, 2, 2, 2, 2, 2, 2, 2, 2147352578, 2, 130050, 2,
534                         130050, 2147352578};
535     testDotProd(s1_3, s2_3, c1_3, c2_3, results_3);
536 
537 
538     short[] s1_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
539     short[] s2_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
540     char[]  c1_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
541     char[]  c2_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S };
542     int[] results_4 = { -1073938429, -1073741811, -1073938429, -1073741811, -1073741811,
543                         -1073741811, -1073938429, 1073840128, -1073840128, 1073840128,
544                         -1073938429, 3, 3, 3, 3, 3, 3, 3, 3, -1073938429, 3, 195075, 3,
545                         195075, -1073938429 };
546     testDotProd(s1_4, s2_4, c1_4, c2_4, results_4);
547   }
548 
main(String[] args)549   public static void main(String[] args) {
550     run();
551   }
552 }
553