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, casted computations.
21  */
22 public class Main {
23 
24   /// CHECK-START: int Main.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,MIPS64}: int Main.sadShort2IntParamRight(short[], short) loop_optimization (after)
37   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
38   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
39   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
40   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Param>>] loop:none
41   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
42   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{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: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
45   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
46   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntParamRight(short[] s, short param)47   private static int sadShort2IntParamRight(short[] s, short param) {
48     int sad = 0;
49     for (int i = 0; i < s.length; i++) {
50       sad += Math.abs(s[i] - param);
51     }
52     return sad;
53   }
54 
55   /// CHECK-START: int Main.sadShort2IntParamLeft(short[], short) loop_optimization (before)
56   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
57   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
58   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
59   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
60   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
61   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
62   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Param>>,<<Get>>]        loop:<<Loop>>      outer_loop:none
63   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
64   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
65   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
66   //
67   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntParamLeft(short[], short) loop_optimization (after)
68   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
69   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
70   /// CHECK-DAG: <<Param:s\d+>>  ParameterValue                 loop:none
71   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Param>>] loop:none
72   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
73   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
74   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
75   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
76   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
77   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntParamLeft(short[] s, short param)78   private static int sadShort2IntParamLeft(short[] s, short param) {
79     int sad = 0;
80     for (int i = 0; i < s.length; i++) {
81       sad += Math.abs(param - s[i]);
82     }
83     return sad;
84   }
85 
86   /// CHECK-START: int Main.sadShort2IntConstRight(short[]) loop_optimization (before)
87   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
88   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
89   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant -32767             loop:none
90   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
91   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
92   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
93   /// CHECK-DAG: <<Add:i\d+>>    Add [<<Get>>,<<ConsI>>]        loop:<<Loop>>      outer_loop:none
94   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Add>>]                  loop:<<Loop>>      outer_loop:none
95   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
96   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
97   //
98   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntConstRight(short[]) loop_optimization (after)
99   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
100   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
101   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
102   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
103   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
104   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
105   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
106   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
107   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
108   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntConstRight(short[] s)109   private static int sadShort2IntConstRight(short[] s) {
110     int sad = 0;
111     for (int i = 0; i < s.length; i++) {
112       sad += Math.abs(s[i] - 32767);
113     }
114     return sad;
115   }
116 
117   /// CHECK-START: int Main.sadShort2IntConstLeft(short[]) loop_optimization (before)
118   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
119   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
120   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
121   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
122   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
123   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
124   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<ConsI>>,<<Get>>]        loop:<<Loop>>      outer_loop:none
125   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
126   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
127   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
128   //
129   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntConstLeft(short[]) loop_optimization (after)
130   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
131   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
132   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 32767              loop:none
133   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
134   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
135   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
136   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
137   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
138   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
139   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntConstLeft(short[] s)140   private static int sadShort2IntConstLeft(short[] s) {
141     int sad = 0;
142     for (int i = 0; i < s.length; i++) {
143       sad += Math.abs(32767 - s[i]);
144     }
145     return sad;
146   }
147 
148   /// CHECK-START: int Main.sadShort2IntInvariantRight(short[], int) loop_optimization (before)
149   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
150   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
151   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
152   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
153   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
154   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
155   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get>>,<<Conv>>]         loop:<<Loop>>      outer_loop:none
156   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
157   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
158   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
159   //
160   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntInvariantRight(short[], int) loop_optimization (after)
161   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
162   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
163   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
164   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Conv>>]  loop:none
165   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
166   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
167   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
168   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
169   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Rep>>] loop:<<Loop>> outer_loop:none
170   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntInvariantRight(short[] s, int val)171   private static int sadShort2IntInvariantRight(short[] s, int val) {
172     int sad = 0;
173     short x = (short) (val + 1);
174     for (int i = 0; i < s.length; i++) {
175       sad += Math.abs(s[i] - x);
176     }
177     return sad;
178   }
179 
180   /// CHECK-START: int Main.sadShort2IntInvariantLeft(short[], int) loop_optimization (before)
181   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
182   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
183   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
184   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
185   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
186   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
187   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Conv>>,<<Get>>]         loop:<<Loop>>      outer_loop:none
188   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
189   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
190   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
191   //
192   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntInvariantLeft(short[], int) loop_optimization (after)
193   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
194   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
195   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [{{i\d+}}]      loop:none
196   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<Conv>>]  loop:none
197   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
198   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
199   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
200   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
201   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Rep>>,<<Load>>] loop:<<Loop>> outer_loop:none
202   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntInvariantLeft(short[] s, int val)203   private static int sadShort2IntInvariantLeft(short[] s, int val) {
204     int sad = 0;
205     short x = (short) (val + 1);
206     for (int i = 0; i < s.length; i++) {
207       sad += Math.abs(x - s[i]);
208     }
209     return sad;
210   }
211 
212   /// CHECK-START: int Main.sadShort2IntCastedExprRight(short[]) loop_optimization (before)
213   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
214   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
215   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
216   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
217   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
218   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
219   /// CHECK-DAG: <<Add:i\d+>>    [<<Get>>,<<ConsI>>]            loop:<<Loop>>      outer_loop:none
220   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [<<Add>>]       loop:<<Loop>>      outer_loop:none
221   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Get>>,<<Conv>>]         loop:<<Loop>>      outer_loop:none
222   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
223   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
224   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
225   //
226   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntCastedExprRight(short[]) loop_optimization (after)
227   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
228   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
229   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
230   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
231   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
232   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
233   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
234   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
235   /// CHECK-DAG: <<Add:d\d+>>    VecAdd [<<Load>>,<<Rep>>]      loop:<<Loop>>      outer_loop:none
236   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Load>>,<<Add>>] loop:<<Loop>> outer_loop:none
237   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntCastedExprRight(short[] s)238   private static int sadShort2IntCastedExprRight(short[] s) {
239     int sad = 0;
240     for (int i = 0; i < s.length; i++) {
241       short x = (short) (s[i] + 110);  // narrower part sign extends
242       sad += Math.abs(s[i] - x);
243     }
244     return sad;
245   }
246 
247   /// CHECK-START: int Main.sadShort2IntCastedExprLeft(short[]) loop_optimization (before)
248   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
249   /// CHECK-DAG: <<Cons1:i\d+>>  IntConstant 1                  loop:none
250   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
251   /// CHECK-DAG: <<Phi2:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
252   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop>>      outer_loop:none
253   /// CHECK-DAG: <<Get:s\d+>>    ArrayGet [{{l\d+}},<<Phi1>>]   loop:<<Loop>>      outer_loop:none
254   /// CHECK-DAG: <<Add:i\d+>>    [<<Get>>,<<ConsI>>]            loop:<<Loop>>      outer_loop:none
255   /// CHECK-DAG: <<Conv:s\d+>>   TypeConversion [<<Add>>]       loop:<<Loop>>      outer_loop:none
256   /// CHECK-DAG: <<Sub:i\d+>>    Sub [<<Conv>>,<<Get>>]         loop:<<Loop>>      outer_loop:none
257   /// CHECK-DAG: <<Intrin:i\d+>> Abs [<<Sub>>]                  loop:<<Loop>>      outer_loop:none
258   /// CHECK-DAG:                 Add [<<Phi2>>,<<Intrin>>]      loop:<<Loop>>      outer_loop:none
259   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons1>>]       loop:<<Loop>>      outer_loop:none
260   //
261   /// CHECK-START-{ARM64,MIPS64}: int Main.sadShort2IntCastedExprLeft(short[]) loop_optimization (after)
262   /// CHECK-DAG: <<Cons0:i\d+>>  IntConstant 0                  loop:none
263   /// CHECK-DAG: <<Cons8:i\d+>>  IntConstant 8                  loop:none
264   /// CHECK-DAG: <<ConsI:i\d+>>  IntConstant 110                loop:none
265   /// CHECK-DAG: <<Rep:d\d+>>    VecReplicateScalar [<<ConsI>>] loop:none
266   /// CHECK-DAG: <<Set:d\d+>>    VecSetScalars [<<Cons0>>]      loop:none
267   /// CHECK-DAG: <<Phi1:i\d+>>   Phi [<<Cons0>>,{{i\d+}}]       loop:<<Loop:B\d+>> outer_loop:none
268   /// CHECK-DAG: <<Phi2:d\d+>>   Phi [<<Set>>,{{d\d+}}]         loop:<<Loop>>      outer_loop:none
269   /// CHECK-DAG: <<Load:d\d+>>   VecLoad [{{l\d+}},<<Phi1>>]    loop:<<Loop>>      outer_loop:none
270   /// CHECK-DAG: <<Add:d\d+>>    VecAdd [<<Load>>,<<Rep>>]      loop:<<Loop>>      outer_loop:none
271   /// CHECK-DAG: <<SAD:d\d+>>    VecSADAccumulate [<<Phi2>>,<<Add>>,<<Load>>] loop:<<Loop>> outer_loop:none
272   /// CHECK-DAG:                 Add [<<Phi1>>,<<Cons8>>]       loop:<<Loop>>      outer_loop:none
sadShort2IntCastedExprLeft(short[] s)273   private static int sadShort2IntCastedExprLeft(short[] s) {
274     int sad = 0;
275     for (int i = 0; i < s.length; i++) {
276       short x = (short) (s[i] + 110);  // narrower part sign extends
277       sad += Math.abs(x - s[i]);
278     }
279     return sad;
280   }
281 
main(String[] args)282   public static void main(String[] args) {
283     short[] interesting = {
284       (short) 0x0000,
285       (short) 0x0001,
286       (short) 0x0002,
287       (short) 0x0003,
288       (short) 0x0004,
289       (short) 0x1234,
290       (short) 0x8000,
291       (short) 0x8001,
292       (short) 0x8002,
293       (short) 0x8003,
294       (short) 0x8004,
295       (short) 0x8004,
296       (short) 0x7000,
297       (short) 0x7fff,
298       (short) 0xf000,
299       (short) 0xffff
300     };
301     short[] s = new short[64];
302     for (int i = 0; i < 64; i++) {
303       s[i] = interesting[i % interesting.length];
304     }
305 
306     expectEquals(1067200, sadShort2IntParamRight(s, (short)-1));
307     expectEquals(1067200, sadShort2IntParamRight(s, (short) 0));
308     expectEquals(1067208, sadShort2IntParamRight(s, (short) 1));
309     expectEquals(1067224, sadShort2IntParamRight(s, (short) 2));
310     expectEquals(2635416, sadShort2IntParamRight(s, (short) 0x7fff));
311     expectEquals(1558824, sadShort2IntParamRight(s, (short) 0x8000));
312 
313     expectEquals(1067200, sadShort2IntParamLeft(s, (short)-1));
314     expectEquals(1067200, sadShort2IntParamLeft(s, (short) 0));
315     expectEquals(1067208, sadShort2IntParamLeft(s, (short) 1));
316     expectEquals(1067224, sadShort2IntParamLeft(s, (short) 2));
317     expectEquals(2635416, sadShort2IntParamLeft(s, (short) 0x7fff));
318     expectEquals(1558824, sadShort2IntParamLeft(s, (short) 0x8000));
319 
320     expectEquals(2635416, sadShort2IntConstRight(s));
321     expectEquals(2635416, sadShort2IntConstLeft(s));
322 
323     expectEquals(1067200, sadShort2IntInvariantRight(s, -2));
324     expectEquals(1067200, sadShort2IntInvariantRight(s, -1));
325     expectEquals(1067208, sadShort2IntInvariantRight(s, 0));
326     expectEquals(1067224, sadShort2IntInvariantRight(s, 1));
327     expectEquals(2635416, sadShort2IntInvariantRight(s, 0x7ffe));
328     expectEquals(1558824, sadShort2IntInvariantRight(s, 0x7fff));
329 
330     expectEquals(1067200, sadShort2IntInvariantLeft(s, -2));
331     expectEquals(1067200, sadShort2IntInvariantLeft(s, -1));
332     expectEquals(1067208, sadShort2IntInvariantLeft(s, 0));
333     expectEquals(1067224, sadShort2IntInvariantLeft(s, 1));
334     expectEquals(2635416, sadShort2IntInvariantLeft(s, 0x7ffe));
335     expectEquals(1558824, sadShort2IntInvariantLeft(s, 0x7fff));
336 
337     expectEquals(268304, sadShort2IntCastedExprLeft(s));
338     expectEquals(268304, sadShort2IntCastedExprRight(s));
339 
340     System.out.println("passed");
341   }
342 
expectEquals(int expected, int result)343   private static void expectEquals(int expected, int result) {
344     if (expected != result) {
345       throw new Error("Expected: " + expected + ", found: " + result);
346     }
347   }
348 
expectEquals(long expected, long result)349   private static void expectEquals(long expected, long result) {
350     if (expected != result) {
351       throw new Error("Expected: " + expected + ", found: " + result);
352     }
353   }
354 }
355