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 
17 /**
18  * Tests for SAD (sum of absolute differences).
19  *
20  * Some special cases: parameters, constants, invariants, cast computations.
21  */
22 public class SimdSadShort3 {
23 
24   /// CHECK-START: int SimdSadShort3.sadShort2IntParamRight(short[], short) loop_optimization (before)
25   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
26   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
27   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
28   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
29   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
30   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
31   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get>>,<<Param>>]        loop:<<Loop>>      outer_loop:none
32   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
33   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
34   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
35   //
36   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntParamRight(short[], short) loop_optimization (after)
37   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
38   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
39   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
40   //
41   //      SAD idiom is not supported for SVE.
42   ///     CHECK-NOT: VecSADAccumulate
43   //
44   /// CHECK-ELSE:
45   //
46   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
47   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Param>>] loop:none
48   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
49   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
50   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
51   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
52   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
53   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
54   //
55   /// CHECK-FI:
sadShort2IntParamRight(short[] s, short param)56   private static int sadShort2IntParamRight(short[] s, short param) {
57     int sad = 0;
58     for (int i = 0; i < s.length; i++) {
59       sad += Math.abs(s[i] - param);
60     }
61     return sad;
62   }
63 
64   /// CHECK-START: int SimdSadShort3.sadShort2IntParamLeft(short[], short) loop_optimization (before)
65   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
66   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
67   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
68   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
69   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
70   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
71   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Param>>,<<Get>>]        loop:<<Loop>>      outer_loop:none
72   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
73   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
74   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
75   //
76   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntParamLeft(short[], short) loop_optimization (after)
77   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
78   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
79   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
80   //
81   //      SAD idiom is not supported for SVE.
82   ///     CHECK-NOT: VecSADAccumulate
83   //
84   /// CHECK-ELSE:
85   //
86   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
87   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Param>>] loop:none
88   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
89   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
90   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
91   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
92   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
93   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
94   //
95   /// CHECK-FI:
sadShort2IntParamLeft(short[] s, short param)96   private static int sadShort2IntParamLeft(short[] s, short param) {
97     int sad = 0;
98     for (int i = 0; i < s.length; i++) {
99       sad += Math.abs(param - s[i]);
100     }
101     return sad;
102   }
103 
104   /// CHECK-START: int SimdSadShort3.sadShort2IntConstRight(short[]) loop_optimization (before)
105   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
106   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
107   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant -32767             loop:none
108   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
109   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
110   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
111   /// CHECK-DAG: <<Add:i\d+>>    Add [<<Get>>,<<ConsI>>]        loop:<<Loop>>      outer_loop:none
112   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Add>>]                  loop:<<Loop>>      outer_loop:none
113   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
114   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
115   //
116   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntConstRight(short[]) loop_optimization (after)
117   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
118   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
119   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
120   //
121   //      SAD idiom is not supported for SVE.
122   ///     CHECK-NOT: VecSADAccumulate
123   //
124   /// CHECK-ELSE:
125   //
126   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
127   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
128   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
129   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
130   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
131   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
132   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
133   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
134   //
135   /// CHECK-FI:
sadShort2IntConstRight(short[] s)136   private static int sadShort2IntConstRight(short[] s) {
137     int sad = 0;
138     for (int i = 0; i < s.length; i++) {
139       sad += Math.abs(s[i] - 32767);
140     }
141     return sad;
142   }
143 
144   /// CHECK-START: int SimdSadShort3.sadShort2IntConstLeft(short[]) loop_optimization (before)
145   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
146   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
147   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
148   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
149   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
150   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
151   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<ConsI>>,<<Get>>]        loop:<<Loop>>      outer_loop:none
152   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
153   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
154   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
155   //
156   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntConstLeft(short[]) loop_optimization (after)
157   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
158   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
159   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
160   //
161   //      SAD idiom is not supported for SVE.
162   ///     CHECK-NOT: VecSADAccumulate
163   //
164   /// CHECK-ELSE:
165   //
166   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
167   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
168   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
169   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
170   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
171   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
172   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
173   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
174   //
175   /// CHECK-FI:
sadShort2IntConstLeft(short[] s)176   private static int sadShort2IntConstLeft(short[] s) {
177     int sad = 0;
178     for (int i = 0; i < s.length; i++) {
179       sad += Math.abs(32767 - s[i]);
180     }
181     return sad;
182   }
183 
184   /// CHECK-START: int SimdSadShort3.sadShort2IntInvariantRight(short[], int) loop_optimization (before)
185   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
186   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
187   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
188   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
189   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
190   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
191   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get>>,<<Conv>>]         loop:<<Loop>>      outer_loop:none
192   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
193   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
194   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
195   //
196   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntInvariantRight(short[], int) loop_optimization (after)
197   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
198   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
199   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
200   //
201   //      SAD idiom is not supported for SVE.
202   ///     CHECK-NOT: VecSADAccumulate
203   //
204   /// CHECK-ELSE:
205   //
206   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
207   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Conv>>]  loop:none
208   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
209   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
210   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
211   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
212   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
213   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
214   //
215   /// CHECK-FI:
sadShort2IntInvariantRight(short[] s, int val)216   private static int sadShort2IntInvariantRight(short[] s, int val) {
217     int sad = 0;
218     short x = (short) (val + 1);
219     for (int i = 0; i < s.length; i++) {
220       sad += Math.abs(s[i] - x);
221     }
222     return sad;
223   }
224 
225   /// CHECK-START: int SimdSadShort3.sadShort2IntInvariantLeft(short[], int) loop_optimization (before)
226   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
227   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
228   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
229   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
230   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
231   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
232   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Conv>>,<<Get>>]         loop:<<Loop>>      outer_loop:none
233   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
234   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
235   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
236   //
237   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntInvariantLeft(short[], int) loop_optimization (after)
238   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
239   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
240   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
241   //
242   //      SAD idiom is not supported for SVE.
243   ///     CHECK-NOT: VecSADAccumulate
244   //
245   /// CHECK-ELSE:
246   //
247   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
248   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Conv>>]  loop:none
249   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
250   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
251   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
252   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
253   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
254   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
255   //
256   /// CHECK-FI:
sadShort2IntInvariantLeft(short[] s, int val)257   private static int sadShort2IntInvariantLeft(short[] s, int val) {
258     int sad = 0;
259     short x = (short) (val + 1);
260     for (int i = 0; i < s.length; i++) {
261       sad += Math.abs(x - s[i]);
262     }
263     return sad;
264   }
265 
266   /// CHECK-START: int SimdSadShort3.sadShort2IntCastExprRight(short[]) loop_optimization (before)
267   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
268   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
269   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
270   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
271   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
272   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
273   /// CHECK-DAG: <<Add:i\d+>>    [<<Get>>,<<ConsI>>]            loop:<<Loop>>      outer_loop:none
274   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [<<Add>>]       loop:<<Loop>>      outer_loop:none
275   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get>>,<<Conv>>]         loop:<<Loop>>      outer_loop:none
276   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
277   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
278   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
279   //
280   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntCastExprRight(short[]) loop_optimization (after)
281   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
282   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
283   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
284   //
285   //      SAD idiom is not supported for SVE.
286   ///     CHECK-NOT: VecSADAccumulate
287   //
288   /// CHECK-ELSE:
289   //
290   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
291   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
292   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
293   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
294   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
295   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
296   ///     CHECK-DAG: <<Add:d\d+>>    VecAdd [<<Load>>,<<Rep>>]      loop:<<Loop>>      outer_loop:none
297   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Add>>] loop:<<Loop>> outer_loop:none
298   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
299   //
300   /// CHECK-FI:
sadShort2IntCastExprRight(short[] s)301   private static int sadShort2IntCastExprRight(short[] s) {
302     int sad = 0;
303     for (int i = 0; i < s.length; i++) {
304       short x = (short) (s[i] + 110);  // narrower part sign extends
305       sad += Math.abs(s[i] - x);
306     }
307     return sad;
308   }
309 
310   /// CHECK-START: int SimdSadShort3.sadShort2IntCastExprLeft(short[]) loop_optimization (before)
311   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
312   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
313   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
314   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
315   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
316   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
317   /// CHECK-DAG: <<Add:i\d+>>    [<<Get>>,<<ConsI>>]            loop:<<Loop>>      outer_loop:none
318   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [<<Add>>]       loop:<<Loop>>      outer_loop:none
319   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Conv>>,<<Get>>]         loop:<<Loop>>      outer_loop:none
320   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
321   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
322   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
323   //
324   /// CHECK-START-ARM64: int SimdSadShort3.sadShort2IntCastExprLeft(short[]) loop_optimization (after)
325   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
326   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
327   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
328   //
329   //      SAD idiom is not supported for SVE.
330   ///     CHECK-NOT: VecSADAccumulate
331   //
332   /// CHECK-ELSE:
333   //
334   ///     CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
335   ///     CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
336   ///     CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
337   ///     CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
338   ///     CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
339   ///     CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
340   ///     CHECK-DAG: <<Add:d\d+>>    VecAdd [<<Load>>,<<Rep>>]      loop:<<Loop>>      outer_loop:none
341   ///     CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Add>>,<<Load>>] loop:<<Loop>> outer_loop:none
342   ///     CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
343   //
344   /// CHECK-FI:
sadShort2IntCastExprLeft(short[] s)345   private static int sadShort2IntCastExprLeft(short[] s) {
346     int sad = 0;
347     for (int i = 0; i < s.length; i++) {
348       short x = (short) (s[i] + 110);  // narrower part sign extends
349       sad += Math.abs(x - s[i]);
350     }
351     return sad;
352   }
353 
main()354   public static void main() {
355     short[] interesting = {
356       (short) 0x0000,
357       (short) 0x0001,
358       (short) 0x0002,
359       (short) 0x0003,
360       (short) 0x0004,
361       (short) 0x1234,
362       (short) 0x8000,
363       (short) 0x8001,
364       (short) 0x8002,
365       (short) 0x8003,
366       (short) 0x8004,
367       (short) 0x8004,
368       (short) 0x7000,
369       (short) 0x7fff,
370       (short) 0xf000,
371       (short) 0xffff
372     };
373     short[] s = new short[64];
374     for (int i = 0; i < 64; i++) {
375       s[i] = interesting[i % interesting.length];
376     }
377 
378     expectEquals(1067200, sadShort2IntParamRight(s, (short)-1));
379     expectEquals(1067200, sadShort2IntParamRight(s, (short) 0));
380     expectEquals(1067208, sadShort2IntParamRight(s, (short) 1));
381     expectEquals(1067224, sadShort2IntParamRight(s, (short) 2));
382     expectEquals(2635416, sadShort2IntParamRight(s, (short) 0x7fff));
383     expectEquals(1558824, sadShort2IntParamRight(s, (short) 0x8000));
384 
385     expectEquals(1067200, sadShort2IntParamLeft(s, (short)-1));
386     expectEquals(1067200, sadShort2IntParamLeft(s, (short) 0));
387     expectEquals(1067208, sadShort2IntParamLeft(s, (short) 1));
388     expectEquals(1067224, sadShort2IntParamLeft(s, (short) 2));
389     expectEquals(2635416, sadShort2IntParamLeft(s, (short) 0x7fff));
390     expectEquals(1558824, sadShort2IntParamLeft(s, (short) 0x8000));
391 
392     expectEquals(2635416, sadShort2IntConstRight(s));
393     expectEquals(2635416, sadShort2IntConstLeft(s));
394 
395     expectEquals(1067200, sadShort2IntInvariantRight(s, -2));
396     expectEquals(1067200, sadShort2IntInvariantRight(s, -1));
397     expectEquals(1067208, sadShort2IntInvariantRight(s, 0));
398     expectEquals(1067224, sadShort2IntInvariantRight(s, 1));
399     expectEquals(2635416, sadShort2IntInvariantRight(s, 0x7ffe));
400     expectEquals(1558824, sadShort2IntInvariantRight(s, 0x7fff));
401 
402     expectEquals(1067200, sadShort2IntInvariantLeft(s, -2));
403     expectEquals(1067200, sadShort2IntInvariantLeft(s, -1));
404     expectEquals(1067208, sadShort2IntInvariantLeft(s, 0));
405     expectEquals(1067224, sadShort2IntInvariantLeft(s, 1));
406     expectEquals(2635416, sadShort2IntInvariantLeft(s, 0x7ffe));
407     expectEquals(1558824, sadShort2IntInvariantLeft(s, 0x7fff));
408 
409     expectEquals(268304, sadShort2IntCastExprLeft(s));
410     expectEquals(268304, sadShort2IntCastExprRight(s));
411 
412     System.out.println("SimdSadShort3 passed");
413   }
414 
expectEquals(int expected, int result)415   private static void expectEquals(int expected, int result) {
416     if (expected != result) {
417       throw new Error("Expected: " + expected + ", found: " + result);
418     }
419   }
420 
expectEquals(long expected, long result)421   private static void expectEquals(long expected, long result) {
422     if (expected != result) {
423       throw new Error("Expected: " + expected + ", found: " + result);
424     }
425   }
426 }
427