• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 halving-add idiomatic vectorization.
19  */
20 public class HaddShort {
21 
22   private static final int N = 64 * 1024;
23   private static final int M = N + 31;
24 
25   static short[] sB1 = new short[M];
26   static short[] sB2 = new short[M];
27   static short[] sBo = new short[M];
28 
$inline$mone()29   private static int $inline$mone() {
30     return -1;
31   }
32 
33   /// CHECK-START: void HaddShort.halving_add_signed(short[], short[], short[]) loop_optimization (before)
34   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
35   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
36   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
37   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
38   /// CHECK-DAG: <<Add:i\d+>>  Add [<<Get1>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
39   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
40   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
41   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
42   //
43   /// CHECK-START-ARM: void HaddShort.halving_add_signed(short[], short[], short[]) loop_optimization (after)
44   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
45   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
46   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
47   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
48   //
49   /// CHECK-START-ARM64: void HaddShort.halving_add_signed(short[], short[], short[]) loop_optimization (after)
50   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
51   //
52   //      HalvingAdd idiom is not supported for SVE.
53   ///     CHECK-NOT: VecHalvingAdd
54   //
55   /// CHECK-ELSE:
56   //
57   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
58   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
59   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
60   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
61   //
62   /// CHECK-FI:
halving_add_signed(short[] b1, short[] b2, short[] bo)63   private static void halving_add_signed(short[] b1, short[] b2, short[] bo) {
64     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
65     for (int i = 0; i < min_length; i++) {
66       bo[i] = (short) ((b1[i] + b2[i]) >> 1);
67     }
68   }
69 
70   /// CHECK-START: void HaddShort.halving_add_signed_alt(short[], short[], short[]) loop_optimization (before)
71   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
72   /// CHECK-DAG: <<I10:i\d+>>  IntConstant 10                      loop:none
73   /// CHECK-DAG: <<M10:i\d+>>  IntConstant -10                     loop:none
74   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
75   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
76   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
77   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<I10>>]              loop:<<Loop>>      outer_loop:none
78   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Get2>>,<<M10>>]              loop:<<Loop>>      outer_loop:none
79   /// CHECK-DAG: <<Add3:i\d+>> Add [<<Add1>>,<<Add2>>]             loop:<<Loop>>      outer_loop:none
80   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add3>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
81   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
82   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
83   //
84   /// CHECK-START-ARM: void HaddShort.halving_add_signed_alt(short[], short[], short[]) loop_optimization (after)
85   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
86   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
87   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
88   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
89   //
90   /// CHECK-START-ARM64: void HaddShort.halving_add_signed_alt(short[], short[], short[]) loop_optimization (after)
91   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
92   //
93   //      HalvingAdd idiom is not supported for SVE.
94   ///     CHECK-NOT: VecHalvingAdd
95   //
96   /// CHECK-ELSE:
97   //
98   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
99   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
100   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
101   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
102   //
103   /// CHECK-FI:
halving_add_signed_alt(short[] b1, short[] b2, short[] bo)104   private static void halving_add_signed_alt(short[] b1, short[] b2, short[] bo) {
105     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
106     for (int i = 0; i < min_length; i++) {
107       // Cancelling constant computations do not confuse recognition.
108       bo[i] = (short) (((b1[i] + 10) + (b2[i] - 10)) >> 1);
109     }
110   }
111 
112   /// CHECK-START: void HaddShort.halving_add_unsigned(short[], short[], short[]) instruction_simplifier (before)
113   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
114   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                   loop:none
115   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
116   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
117   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
118   /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>]             loop:<<Loop>>      outer_loop:none
119   /// CHECK-DAG: <<And2:i\d+>> And [<<UMAX>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
120   /// CHECK-DAG: <<Add:i\d+>>  Add [<<And1>>,<<And2>>]             loop:<<Loop>>      outer_loop:none
121   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
122   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
123   /// CHECK-DAG:               ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>>      outer_loop:none
124   //
125   /// CHECK-START: void HaddShort.halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
126   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
127   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
128   /// CHECK-DAG: <<Get1:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
129   /// CHECK-DAG: <<Get2:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
130   /// CHECK-DAG: <<Add:i\d+>>  Add [<<Get1>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
131   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
132   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
133   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
134   //
135   /// CHECK-START-ARM: void HaddShort.halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
136   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
137   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
138   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none
139   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
140   //
141   /// CHECK-START-ARM64: void HaddShort.halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
142   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
143   //
144   //      HalvingAdd idiom is not supported for SVE.
145   ///     CHECK-NOT: VecHalvingAdd
146   //
147   /// CHECK-ELSE:
148   //
149   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
150   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
151   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none
152   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
153   //
154   /// CHECK-FI:
halving_add_unsigned(short[] b1, short[] b2, short[] bo)155   private static void halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
156     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
157     for (int i = 0; i < min_length; i++) {
158       int v1 = b1[i] & 0xffff;
159       int v2 = b2[i] & 0xffff;
160       bo[i] = (short) ((v1 + v2) >> 1);
161     }
162   }
163 
164   /// CHECK-START: void HaddShort.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (before)
165   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
166   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
167   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
168   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
169   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
170   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
171   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
172   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
173   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
174   //
175   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after)
176   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
177   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
178   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
179   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
180   //
181   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after)
182   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
183   //
184   //      HalvingAdd idiom is not supported for SVE.
185   ///     CHECK-NOT: VecHalvingAdd
186   //
187   /// CHECK-ELSE:
188   //
189   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
190   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
191   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
192   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
193   //
194   /// CHECK-FI:
rounding_halving_add_signed(short[] b1, short[] b2, short[] bo)195   private static void rounding_halving_add_signed(short[] b1, short[] b2, short[] bo) {
196     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
197     for (int i = 0; i < min_length; i++) {
198       bo[i] = (short) ((b1[i] + b2[i] + 1) >> 1);
199     }
200   }
201 
202   /// CHECK-START: void HaddShort.rounding_halving_add_signed_alt(short[], short[], short[]) loop_optimization (before)
203   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
204   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
205   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
206   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
207   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
208   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
209   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
210   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
211   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
212   //
213   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_signed_alt(short[], short[], short[]) loop_optimization (after)
214   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
215   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
216   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
217   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
218   //
219   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_signed_alt(short[], short[], short[]) loop_optimization (after)
220   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
221   //
222   //      HalvingAdd idiom is not supported for SVE.
223   ///     CHECK-NOT: VecHalvingAdd
224   //
225   /// CHECK-ELSE:
226   //
227   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
228   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
229   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
230   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
231   //
232   /// CHECK-FI:
rounding_halving_add_signed_alt(short[] b1, short[] b2, short[] bo)233   private static void rounding_halving_add_signed_alt(short[] b1, short[] b2, short[] bo) {
234     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
235     for (int i = 0; i < min_length; i++) {
236       // Slightly different order in idiom does not confuse recognition.
237       bo[i] = (short) (((1 + b1[i]) + b2[i]) >> 1);
238     }
239   }
240 
241   /// CHECK-START: void HaddShort.rounding_halving_add_signed_alt2(short[], short[], short[]) loop_optimization (before)
242   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
243   /// CHECK-DAG: <<I10:i\d+>>  IntConstant 10                      loop:none
244   /// CHECK-DAG: <<M9:i\d+>>   IntConstant -9                      loop:none
245   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
246   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
247   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
248   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<I10>>]              loop:<<Loop>>      outer_loop:none
249   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Get2>>,<<M9>>]               loop:<<Loop>>      outer_loop:none
250   /// CHECK-DAG: <<Add3:i\d+>> Add [<<Add1>>,<<Add2>>]             loop:<<Loop>>      outer_loop:none
251   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add3>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
252   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
253   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
254   //
255   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_signed_alt2(short[], short[], short[]) loop_optimization (after)
256   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
257   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
258   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
259   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
260   //
261   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_signed_alt2(short[], short[], short[]) loop_optimization (after)
262   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
263   //
264   //      HalvingAdd idiom is not supported for SVE.
265   ///     CHECK-NOT: VecHalvingAdd
266   //
267   /// CHECK-ELSE:
268   //
269   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
270   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
271   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
272   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
273   //
274   /// CHECK-FI:
rounding_halving_add_signed_alt2(short[] b1, short[] b2, short[] bo)275   private static void rounding_halving_add_signed_alt2(short[] b1, short[] b2, short[] bo) {
276     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
277     for (int i = 0; i < min_length; i++) {
278       // Computations that cancel to adding 1 also do not confuse recognition.
279       bo[i] = (short) (((b1[i] + 10) + (b2[i] - 9)) >> 1);
280     }
281   }
282 
283   /// CHECK-START: void HaddShort.rounding_halving_add_signed_alt3(short[], short[], short[]) loop_optimization (before)
284   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
285   /// CHECK-DAG: <<M1:i\d+>>   IntConstant -1                      loop:none
286   /// CHECK-DAG: <<I9:i\d+>>   IntConstant 9                       loop:none
287   /// CHECK-DAG: <<M9:i\d+>>   IntConstant -9                      loop:none
288   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
289   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
290   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
291   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<I9>>]               loop:<<Loop>>      outer_loop:none
292   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Get2>>,<<M9>>]               loop:<<Loop>>      outer_loop:none
293   /// CHECK-DAG: <<Add3:i\d+>> Add [<<Add1>>,<<Add2>>]             loop:<<Loop>>      outer_loop:none
294   /// CHECK-DAG: <<Sub:i\d+>>  Sub [<<Add3>>,<<M1>>]               loop:<<Loop>>      outer_loop:none
295   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Sub>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
296   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
297   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
298   //
299   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_signed_alt3(short[], short[], short[]) loop_optimization (after)
300   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
301   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
302   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
303   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
304   //
305   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_signed_alt3(short[], short[], short[]) loop_optimization (after)
306   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
307   //
308   //      HalvingAdd idiom is not supported for SVE.
309   ///     CHECK-NOT: VecHalvingAdd
310   //
311   /// CHECK-ELSE:
312   //
313   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
314   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
315   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none
316   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
317   //
318   /// CHECK-FI:
rounding_halving_add_signed_alt3(short[] b1, short[] b2, short[] bo)319   private static void rounding_halving_add_signed_alt3(short[] b1, short[] b2, short[] bo) {
320     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
321     for (int i = 0; i < min_length; i++) {
322       // Computations that cancel to adding 1 also do not confuse recognition.
323       bo[i] = (short) (((b1[i] + 9) + (b2[i] - 9) - $inline$mone()) >> 1);
324     }
325   }
326 
327   /// CHECK-START: void HaddShort.rounding_halving_add_unsigned(short[], short[], short[]) instruction_simplifier (before)
328   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
329   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                   loop:none
330   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
331   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
332   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
333   /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>]             loop:<<Loop>>      outer_loop:none
334   /// CHECK-DAG: <<And2:i\d+>> And [<<UMAX>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
335   /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>]             loop:<<Loop>>      outer_loop:none
336   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
337   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
338   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
339   /// CHECK-DAG:               ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>>      outer_loop:none
340   //
341   /// CHECK-START: void HaddShort.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
342   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
343   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
344   /// CHECK-DAG: <<Get1:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
345   /// CHECK-DAG: <<Get2:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
346   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
347   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
348   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
349   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
350   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
351   //
352   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
353   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
354   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
355   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none
356   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
357   //
358   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
359   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
360   //
361   //      HalvingAdd idiom is not supported for SVE.
362   ///     CHECK-NOT: VecHalvingAdd
363   //
364   /// CHECK-ELSE:
365   //
366   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
367   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
368   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none
369   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
370   //
371   /// CHECK-FI:
rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo)372   private static void rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
373     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
374     for (int i = 0; i < min_length; i++) {
375       int v1 = b1[i] & 0xffff;
376       int v2 = b2[i] & 0xffff;
377       bo[i] = (short) ((v1 + v2 + 1) >> 1);
378     }
379   }
380 
381   /// CHECK-START: void HaddShort.rounding_halving_add_unsigned_alt(short[], short[], short[]) instruction_simplifier (before)
382   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
383   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                   loop:none
384   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
385   /// CHECK-DAG: <<Get1:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
386   /// CHECK-DAG: <<Get2:s\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
387   /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>]             loop:<<Loop>>      outer_loop:none
388   /// CHECK-DAG: <<And2:i\d+>> And [<<UMAX>>,<<Get2>>]             loop:<<Loop>>      outer_loop:none
389   /// CHECK-DAG: <<Add1:i\d+>> Add [<<And2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
390   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<And1>>]             loop:<<Loop>>      outer_loop:none
391   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
392   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
393   /// CHECK-DAG:               ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>>      outer_loop:none
394   //
395   /// CHECK-START: void HaddShort.rounding_halving_add_unsigned_alt(short[], short[], short[]) loop_optimization (before)
396   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
397   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
398   /// CHECK-DAG: <<Get1:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
399   /// CHECK-DAG: <<Get2:c\d+>> ArrayGet                            loop:<<Loop>>      outer_loop:none
400   /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
401   /// CHECK-DAG: <<Add2:i\d+>> Add [<<Get1>>,<<Add1>>]             loop:<<Loop>>      outer_loop:none
402   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add2>>,<<I1>>]               loop:<<Loop>>      outer_loop:none
403   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
404   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
405   //
406   /// CHECK-START-ARM: void HaddShort.rounding_halving_add_unsigned_alt(short[], short[], short[]) loop_optimization (after)
407   /// CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
408   /// CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
409   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none
410   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
411   //
412   /// CHECK-START-ARM64: void HaddShort.rounding_halving_add_unsigned_alt(short[], short[], short[]) loop_optimization (after)
413   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
414   //
415   //      HalvingAdd idiom is not supported for SVE.
416   ///     CHECK-NOT: VecHalvingAdd
417   //
418   /// CHECK-ELSE:
419   //
420   ///     CHECK-DAG: <<Get1:d\d+>> VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
421   ///     CHECK-DAG: <<Get2:d\d+>> VecLoad                               loop:<<Loop>>      outer_loop:none
422   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none
423   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
424   //
425   /// CHECK-FI:
rounding_halving_add_unsigned_alt(short[] b1, short[] b2, short[] bo)426   private static void rounding_halving_add_unsigned_alt(short[] b1, short[] b2, short[] bo) {
427     int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
428     for (int i = 0; i < min_length; i++) {
429       // Slightly different order in idiom does not confuse recognition.
430       int v1 = b1[i] & 0xffff;
431       int v2 = b2[i] & 0xffff;
432       bo[i] = (short) (v1 + (v2 + 1) >> 1);
433     }
434   }
435 
436   /// CHECK-START: void HaddShort.halving_add_signed_constant(short[], short[]) loop_optimization (before)
437   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
438   /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767                   loop:none
439   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
440   /// CHECK-DAG: <<Get:s\d+>>  ArrayGet                            loop:<<Loop>>      outer_loop:none
441   /// CHECK-DAG: <<Add:i\d+>>  Add [<<Get>>,<<SMAX>>]              loop:<<Loop>>      outer_loop:none
442   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
443   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
444   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
445   //
446   /// CHECK-START-ARM: void HaddShort.halving_add_signed_constant(short[], short[]) loop_optimization (after)
447   /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767                     loop:none
448   /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>]         loop:none
449   /// CHECK-DAG: <<Get:d\d+>>  VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
450   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
451   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
452   //
453   /// CHECK-START-ARM64: void HaddShort.halving_add_signed_constant(short[], short[]) loop_optimization (after)
454   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
455   //
456   //      HalvingAdd idiom is not supported for SVE.
457   ///     CHECK-NOT: VecHalvingAdd
458   //
459   /// CHECK-ELSE:
460   //
461   ///     CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767                     loop:none
462   ///     CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>]         loop:none
463   ///     CHECK-DAG: <<Get:d\d+>>  VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
464   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none
465   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
466   //
467   /// CHECK-FI:
halving_add_signed_constant(short[] b1, short[] bo)468   private static void halving_add_signed_constant(short[] b1, short[] bo) {
469     int min_length = Math.min(bo.length, b1.length);
470     for (int i = 0; i < min_length; i++) {
471       bo[i] = (short) ((b1[i] + 0x7fff) >> 1);
472     }
473   }
474 
475   /// CHECK-START: void HaddShort.halving_add_unsigned_constant(short[], short[]) instruction_simplifier (before)
476   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
477   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                   loop:none
478   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
479   /// CHECK-DAG: <<Get:s\d+>>  ArrayGet                            loop:<<Loop>>      outer_loop:none
480   /// CHECK-DAG: <<And:i\d+>>  And [<<Get>>,<<UMAX>>]              loop:<<Loop>>      outer_loop:none
481   /// CHECK-DAG: <<Add:i\d+>>  Add [<<And>>,<<UMAX>>]              loop:<<Loop>>      outer_loop:none
482   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
483   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
484   /// CHECK-DAG:               ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>>      outer_loop:none
485   //
486   /// CHECK-START: void HaddShort.halving_add_unsigned_constant(short[], short[]) loop_optimization (before)
487   /// CHECK-DAG: <<I1:i\d+>>   IntConstant 1                       loop:none
488   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                   loop:none
489   /// CHECK-DAG: <<Phi:i\d+>>  Phi                                 loop:<<Loop:B\d+>> outer_loop:none
490   /// CHECK-DAG: <<Get:c\d+>>  ArrayGet                            loop:<<Loop>>      outer_loop:none
491   /// CHECK-DAG: <<Add:i\d+>>  Add [<<Get>>,<<UMAX>>]              loop:<<Loop>>      outer_loop:none
492   /// CHECK-DAG: <<Shr:i\d+>>  Shr [<<Add>>,<<I1>>]                loop:<<Loop>>      outer_loop:none
493   /// CHECK-DAG: <<Cnv:s\d+>>  TypeConversion [<<Shr>>]            loop:<<Loop>>      outer_loop:none
494   /// CHECK-DAG:               ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>>      outer_loop:none
495   //
496   /// CHECK-START-ARM: void HaddShort.halving_add_unsigned_constant(short[], short[]) loop_optimization (after)
497   /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                     loop:none
498   /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>]         loop:none
499   /// CHECK-DAG: <<Get:d\d+>>  VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
500   /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none
501   /// CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
502   //
503   /// CHECK-START-ARM64: void HaddShort.halving_add_unsigned_constant(short[], short[]) loop_optimization (after)
504   /// CHECK-IF:     hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true'
505   //
506   //      HalvingAdd idiom is not supported for SVE.
507   ///     CHECK-NOT: VecHalvingAdd
508   //
509   /// CHECK-ELSE:
510   //
511   ///     CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535                     loop:none
512   ///     CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>]         loop:none
513   ///     CHECK-DAG: <<Get:d\d+>>  VecLoad                               loop:<<Loop:B\d+>> outer_loop:none
514   ///     CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none
515   ///     CHECK-DAG:               VecStore [{{l\d+}},{{i\d+}},<<HAdd>>] loop:<<Loop>>      outer_loop:none
516   //
517   /// CHECK-FI:
halving_add_unsigned_constant(short[] b1, short[] bo)518   private static void halving_add_unsigned_constant(short[] b1, short[] bo) {
519     int min_length = Math.min(bo.length, b1.length);
520     for (int i = 0; i < min_length; i++) {
521       bo[i] = (short) (((b1[i] & 0xffff) + 0xffff) >> 1);
522     }
523   }
524 
main()525   public static void main() {
526     // Some interesting values.
527     short[] interesting = {
528       (short) 0x0000,
529       (short) 0x0001,
530       (short) 0x0002,
531       (short) 0x1234,
532       (short) 0x8000,
533       (short) 0x8001,
534       (short) 0x7fff,
535       (short) 0xffff
536     };
537     // Initialize cross-values to test all cases, and also
538     // set up some extra values to exercise the cleanup loop.
539     for (int i = 0; i < M; i++) {
540       sB1[i] = (short) i;
541       sB2[i] = interesting[i & 7];
542     }
543 
544     // Test halving add idioms.
545     halving_add_signed(sB1, sB2, sBo);
546     for (int i = 0; i < M; i++) {
547       short e = (short) ((sB1[i] + sB2[i]) >> 1);
548       expectEquals(e, sBo[i]);
549     }
550     halving_add_signed_alt(sB1, sB2, sBo);
551     for (int i = 0; i < M; i++) {
552       short e = (short) ((sB1[i] + sB2[i]) >> 1);
553       expectEquals(e, sBo[i]);
554     }
555     halving_add_unsigned(sB1, sB2, sBo);
556     for (int i = 0; i < M; i++) {
557       short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff)) >> 1);
558       expectEquals(e, sBo[i]);
559     }
560     rounding_halving_add_signed(sB1, sB2, sBo);
561     for (int i = 0; i < M; i++) {
562       short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
563       expectEquals(e, sBo[i]);
564     }
565     rounding_halving_add_signed_alt(sB1, sB2, sBo);
566     for (int i = 0; i < M; i++) {
567       short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
568       expectEquals(e, sBo[i]);
569     }
570     rounding_halving_add_signed_alt2(sB1, sB2, sBo);
571     for (int i = 0; i < M; i++) {
572       short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
573       expectEquals(e, sBo[i]);
574     }
575     rounding_halving_add_signed_alt3(sB1, sB2, sBo);
576     for (int i = 0; i < M; i++) {
577       short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
578       expectEquals(e, sBo[i]);
579     }
580     rounding_halving_add_unsigned(sB1, sB2, sBo);
581     for (int i = 0; i < M; i++) {
582       short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff) + 1) >> 1);
583       expectEquals(e, sBo[i]);
584     }
585     rounding_halving_add_unsigned_alt(sB1, sB2, sBo);
586     for (int i = 0; i < M; i++) {
587       short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff) + 1) >> 1);
588       expectEquals(e, sBo[i]);
589     }
590     halving_add_signed_constant(sB1, sBo);
591     for (int i = 0; i < M; i++) {
592       short e = (short) ((sB1[i] + 0x7fff) >> 1);
593       expectEquals(e, sBo[i]);
594     }
595     halving_add_unsigned_constant(sB1, sBo);
596     for (int i = 0; i < M; i++) {
597       short e = (short) (((sB1[i] & 0xffff) + 0xffff) >> 1);
598       expectEquals(e, sBo[i]);
599     }
600 
601     System.out.println("HaddShort passed");
602   }
603 
expectEquals(int expected, int result)604   private static void expectEquals(int expected, int result) {
605     if (expected != result) {
606       throw new Error("Expected: " + expected + ", found: " + result);
607     }
608   }
609 }
610