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 ABS vectorization.
19  */
20 public class Main {
21 
22   private final static boolean isDalvik =
23       System.getProperty("java.vm.name").equals("Dalvik");
24 
25   private static final int SPQUIET = 1 << 22;
26   private static final long DPQUIET = 1L << 51;
27 
28   /// CHECK-START: void Main.doitByte(byte[]) loop_optimization (before)
29   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
30   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
31   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
32   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
33   //
34   /// CHECK-START-ARM: void Main.doitByte(byte[]) loop_optimization (after)
35   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
36   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
37   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
38   /// CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
39   /// CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
40   /// CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
41   //
42   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
43   //
44   /// CHECK-START-ARM64: void Main.doitByte(byte[]) loop_optimization (after)
45   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
46   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
47   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
48   /// CHECK-IF:     hasIsaFeature("sve")
49   //
50   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
51   ///     CHECK-NOT: ArrayGet
52   ///     CHECK-NOT: Abs
53   ///     CHECK-NOT: ArraySet
54   //
55   /// CHECK-ELSE:
56   //
57   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
58   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
59   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
60   //
61   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
62   //
63   /// CHECK-FI:
64   //
doitByte(byte[] x)65   private static void doitByte(byte[] x) {
66     for (int i = 0; i < x.length; i++) {
67       x[i] = (byte) Math.abs(x[i]);
68     }
69   }
70 
71   /// CHECK-START: void Main.doitChar(char[]) loop_optimization (before)
72   /// CHECK-NOT: Abs
73   //
74   /// CHECK-START: void Main.doitChar(char[]) loop_optimization (after)
75   /// CHECK-NOT: VecAbs
doitChar(char[] x)76   private static void doitChar(char[] x) {
77     // Basically a nop due to zero extension.
78     for (int i = 0; i < x.length; i++) {
79       x[i] = (char) Math.abs(x[i]);
80     }
81   }
82 
83   /// CHECK-START: void Main.doitShort(short[]) loop_optimization (before)
84   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
85   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
86   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
87   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
88   //
89   /// CHECK-START-ARM: void Main.doitShort(short[]) loop_optimization (after)
90   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
91   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
92   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
93   /// CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
94   /// CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
95   /// CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
96   //
97   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
98   //
99   /// CHECK-START-ARM64: void Main.doitShort(short[]) loop_optimization (after)
100   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
101   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
102   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
103   /// CHECK-IF:     hasIsaFeature("sve")
104   //
105   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
106   ///     CHECK-NOT: ArrayGet
107   ///     CHECK-NOT: Abs
108   ///     CHECK-NOT: ArraySet
109   //
110   /// CHECK-ELSE:
111   //
112   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
113   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
114   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
115   //
116   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
117   //
118   /// CHECK-FI:
doitShort(short[] x)119   private static void doitShort(short[] x) {
120     for (int i = 0; i < x.length; i++) {
121       x[i] = (short) Math.abs(x[i]);
122     }
123   }
124 
125   /// CHECK-START: void Main.doitCastedChar(char[]) loop_optimization (before)
126   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
127   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
128   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
129   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
130   //
131   /// CHECK-START-ARM64: void Main.doitCastedChar(char[]) loop_optimization (after)
132   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
133   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
134   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
135   /// CHECK-IF:     hasIsaFeature("sve")
136   //
137   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
138   ///     CHECK-NOT: ArrayGet
139   ///     CHECK-NOT: Abs
140   ///     CHECK-NOT: ArraySet
141   //
142   /// CHECK-ELSE:
143   //
144   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
145   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
146   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
147   //
148   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
149   //
150   /// CHECK-FI:
doitCastedChar(char[] x)151   private static void doitCastedChar(char[] x) {
152     for (int i = 0; i < x.length; i++) {
153       x[i] = (char) Math.abs((short) x[i]);
154     }
155   }
156 
157   /// CHECK-START: void Main.doitInt(int[]) loop_optimization (before)
158   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
159   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
160   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
161   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
162   //
163   /// CHECK-START-ARM: void Main.doitInt(int[]) loop_optimization (after)
164   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
165   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
166   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
167   /// CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
168   /// CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
169   /// CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
170   //
171   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
172   //
173   /// CHECK-START-ARM64: void Main.doitInt(int[]) loop_optimization (after)
174   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
175   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
176   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
177   /// CHECK-IF:     hasIsaFeature("sve")
178   //
179   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
180   ///     CHECK-NOT: ArrayGet
181   ///     CHECK-NOT: Abs
182   ///     CHECK-NOT: ArraySet
183   //
184   /// CHECK-ELSE:
185   //
186   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
187   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
188   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
189   //
190   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
191   //
192   /// CHECK-FI:
doitInt(int[] x)193   private static void doitInt(int[] x) {
194     for (int i = 0; i < x.length; i++) {
195       x[i] = Math.abs(x[i]);
196     }
197   }
198 
199   /// CHECK-START: void Main.doitLong(long[]) loop_optimization (before)
200   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
201   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
202   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
203   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
204   //
205   /// CHECK-START-ARM64: void Main.doitLong(long[]) loop_optimization (after)
206   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
207   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
208   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
209   /// CHECK-IF:     hasIsaFeature("sve")
210   //
211   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
212   ///     CHECK-NOT: ArrayGet
213   ///     CHECK-NOT: Abs
214   ///     CHECK-NOT: ArraySet
215   //
216   /// CHECK-ELSE:
217   //
218   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
219   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
220   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
221   //
222   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
223   //
224   /// CHECK-FI:
doitLong(long[] x)225   private static void doitLong(long[] x) {
226     for (int i = 0; i < x.length; i++) {
227       x[i] = Math.abs(x[i]);
228     }
229   }
230 
231   /// CHECK-START: void Main.doitFloat(float[]) loop_optimization (before)
232   /// CHECK-DAG: Phi       loop:<<Loop:B\d+>> outer_loop:none
233   /// CHECK-DAG: ArrayGet  loop:<<Loop>>      outer_loop:none
234   /// CHECK-DAG: Abs       loop:<<Loop>>      outer_loop:none
235   /// CHECK-DAG: ArraySet  loop:<<Loop>>      outer_loop:none
236   //
237   /// CHECK-START-ARM64: void Main.doitFloat(float[]) loop_optimization (after)
238   /// CHECK-DAG: VecLoad   loop:<<Loop1:B\d+>> outer_loop:none
239   /// CHECK-DAG: VecAbs    loop:<<Loop1>>      outer_loop:none
240   /// CHECK-DAG: VecStore  loop:<<Loop1>>      outer_loop:none
241   /// CHECK-IF:     hasIsaFeature("sve")
242   //
243   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
244   ///     CHECK-NOT: ArrayGet
245   ///     CHECK-NOT: Abs
246   ///     CHECK-NOT: ArraySet
247   //
248   /// CHECK-ELSE:
249   //
250   ///     CHECK-DAG: ArrayGet  loop:<<Loop2:B\d+>> outer_loop:none
251   ///     CHECK-DAG: Abs       loop:<<Loop2>>      outer_loop:none
252   ///     CHECK-DAG: ArraySet  loop:<<Loop2>>      outer_loop:none
253   //
254   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
255   //
256   /// CHECK-FI:
doitFloat(float[] x)257   private static void doitFloat(float[] x) {
258     for (int i = 0; i < x.length; i++) {
259       x[i] = Math.abs(x[i]);
260     }
261   }
262 
263   /// CHECK-START: void Main.doitDouble(double[]) loop_optimization (before)
264   /// CHECK-DAG: Phi        loop:<<Loop:B\d+>> outer_loop:none
265   /// CHECK-DAG: ArrayGet   loop:<<Loop>>      outer_loop:none
266   /// CHECK-DAG: Abs        loop:<<Loop>>      outer_loop:none
267   /// CHECK-DAG: ArraySet   loop:<<Loop>>      outer_loop:none
268   //
269   /// CHECK-START-ARM64: void Main.doitDouble(double[]) loop_optimization (after)
270   /// CHECK-DAG: VecLoad    loop:<<Loop1:B\d+>> outer_loop:none
271   /// CHECK-DAG: VecAbs     loop:<<Loop1>>      outer_loop:none
272   /// CHECK-DAG: VecStore   loop:<<Loop1>>      outer_loop:none
273   /// CHECK-IF:     hasIsaFeature("sve")
274   //
275   ///     CHECK-DAG: VecPredWhile loop:<<Loop1>> outer_loop:none
276   ///     CHECK-NOT: ArrayGet
277   ///     CHECK-NOT: Abs
278   ///     CHECK-NOT: ArraySet
279   //
280   /// CHECK-ELSE:
281   //
282   ///     CHECK-DAG: ArrayGet   loop:<<Loop2:B\d+>> outer_loop:none
283   ///     CHECK-DAG: Abs        loop:<<Loop2>>      outer_loop:none
284   ///     CHECK-DAG: ArraySet   loop:<<Loop2>>      outer_loop:none
285   //
286   ///     CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
287   //
288   /// CHECK-FI:
doitDouble(double[] x)289   private static void doitDouble(double[] x) {
290     for (int i = 0; i < x.length; i++) {
291       x[i] = Math.abs(x[i]);
292     }
293   }
294 
main(String[] args)295   public static void main(String[] args) {
296     // Bytes, chars, shorts.
297     byte[] xb = new byte[256];
298     for (int i = 0; i < 256; i++) {
299       xb[i] = (byte) i;
300     }
301     doitByte(xb);
302     for (int i = 0; i < 256; i++) {
303       expectEquals32((byte) Math.abs((byte) i), xb[i]);
304     }
305     char[] xc = new char[1024 * 64];
306     for (int i = 0; i < 1024 * 64; i++) {
307       xc[i] = (char) i;
308     }
309     doitChar(xc);
310     for (int i = 0; i < 1024 * 64; i++) {
311       expectEquals32((char) Math.abs((char) i), xc[i]);
312     }
313     short[] xs = new short[1024 * 64];
314     for (int i = 0; i < 1024 * 64; i++) {
315       xs[i] = (short) i;
316     }
317     doitShort(xs);
318     for (int i = 0; i < 1024 * 64; i++) {
319       expectEquals32((short) Math.abs((short) i), xs[i]);
320     }
321     for (int i = 0; i < 1024 * 64; i++) {
322       xc[i] = (char) i;
323     }
324     doitCastedChar(xc);
325     for (int i = 0; i < 1024 * 64; i++) {
326       expectEquals32((char) Math.abs((short) i), xc[i]);
327     }
328     // Set up minint32, maxint32 and some others.
329     int[] xi = new int[8];
330     xi[0] = 0x80000000;
331     xi[1] = 0x7fffffff;
332     xi[2] = 0x80000001;
333     xi[3] = -13;
334     xi[4] = -1;
335     xi[5] = 0;
336     xi[6] = 1;
337     xi[7] = 999;
338     doitInt(xi);
339     expectEquals32(0x80000000, xi[0]);
340     expectEquals32(0x7fffffff, xi[1]);
341     expectEquals32(0x7fffffff, xi[2]);
342     expectEquals32(13, xi[3]);
343     expectEquals32(1, xi[4]);
344     expectEquals32(0, xi[5]);
345     expectEquals32(1, xi[6]);
346     expectEquals32(999, xi[7]);
347 
348     // Set up minint64, maxint64 and some others.
349     long[] xl = new long[8];
350     xl[0] = 0x8000000000000000L;
351     xl[1] = 0x7fffffffffffffffL;
352     xl[2] = 0x8000000000000001L;
353     xl[3] = -13;
354     xl[4] = -1;
355     xl[5] = 0;
356     xl[6] = 1;
357     xl[7] = 999;
358     doitLong(xl);
359     expectEquals64(0x8000000000000000L, xl[0]);
360     expectEquals64(0x7fffffffffffffffL, xl[1]);
361     expectEquals64(0x7fffffffffffffffL, xl[2]);
362     expectEquals64(13, xl[3]);
363     expectEquals64(1, xl[4]);
364     expectEquals64(0, xl[5]);
365     expectEquals64(1, xl[6]);
366     expectEquals64(999, xl[7]);
367 
368     // Set up float NaN and some others.
369     float[] xf = new float[16];
370     xf[0] = Float.intBitsToFloat(0x7f800001);
371     xf[1] = Float.intBitsToFloat(0x7fa00000);
372     xf[2] = Float.intBitsToFloat(0x7fc00000);
373     xf[3] = Float.intBitsToFloat(0x7fffffff);
374     xf[4] = Float.intBitsToFloat(0xff800001);
375     xf[5] = Float.intBitsToFloat(0xffa00000);
376     xf[6] = Float.intBitsToFloat(0xffc00000);
377     xf[7] = Float.intBitsToFloat(0xffffffff);
378     xf[8] = Float.NEGATIVE_INFINITY;
379     xf[9] = -99.2f;
380     xf[10] = -1.0f;
381     xf[11] = -0.0f;
382     xf[12] = +0.0f;
383     xf[13] = +1.0f;
384     xf[14] = +99.2f;
385     xf[15] = Float.POSITIVE_INFINITY;
386     doitFloat(xf);
387     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[0]));
388     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[1]));
389     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[2]));
390     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[3]));
391     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[4]));
392     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[5]));
393     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[6]));
394     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[7]));
395     expectEquals32(
396         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
397         Float.floatToRawIntBits(xf[8]));
398     expectEquals32(
399         Float.floatToRawIntBits(99.2f),
400         Float.floatToRawIntBits(xf[9]));
401     expectEquals32(
402         Float.floatToRawIntBits(1.0f),
403         Float.floatToRawIntBits(xf[10]));
404     expectEquals32(0, Float.floatToRawIntBits(xf[11]));
405     expectEquals32(0, Float.floatToRawIntBits(xf[12]));
406     expectEquals32(
407         Float.floatToRawIntBits(1.0f),
408         Float.floatToRawIntBits(xf[13]));
409     expectEquals32(
410         Float.floatToRawIntBits(99.2f),
411         Float.floatToRawIntBits(xf[14]));
412     expectEquals32(
413         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
414         Float.floatToRawIntBits(xf[15]));
415 
416     // Set up double NaN and some others.
417     double[] xd = new double[16];
418     xd[0] = Double.longBitsToDouble(0x7ff0000000000001L);
419     xd[1] = Double.longBitsToDouble(0x7ff4000000000000L);
420     xd[2] = Double.longBitsToDouble(0x7ff8000000000000L);
421     xd[3] = Double.longBitsToDouble(0x7fffffffffffffffL);
422     xd[4] = Double.longBitsToDouble(0xfff0000000000001L);
423     xd[5] = Double.longBitsToDouble(0xfff4000000000000L);
424     xd[6] = Double.longBitsToDouble(0xfff8000000000000L);
425     xd[7] = Double.longBitsToDouble(0xffffffffffffffffL);
426     xd[8] = Double.NEGATIVE_INFINITY;
427     xd[9] = -99.2f;
428     xd[10] = -1.0f;
429     xd[11] = -0.0f;
430     xd[12] = +0.0f;
431     xd[13] = +1.0f;
432     xd[14] = +99.2f;
433     xd[15] = Double.POSITIVE_INFINITY;
434     doitDouble(xd);
435     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[0]));
436     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[1]));
437     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[2]));
438     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[3]));
439     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[4]));
440     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[5]));
441     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[6]));
442     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[7]));
443     expectEquals64(
444         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
445         Double.doubleToRawLongBits(xd[8]));
446     expectEquals64(
447         Double.doubleToRawLongBits(99.2f),
448         Double.doubleToRawLongBits(xd[9]));
449     expectEquals64(
450         Double.doubleToRawLongBits(1.0f),
451         Double.doubleToRawLongBits(xd[10]));
452     expectEquals64(0, Double.doubleToRawLongBits(xd[11]));
453     expectEquals64(0, Double.doubleToRawLongBits(xd[12]));
454     expectEquals64(
455         Double.doubleToRawLongBits(1.0f),
456         Double.doubleToRawLongBits(xd[13]));
457     expectEquals64(
458         Double.doubleToRawLongBits(99.2f),
459         Double.doubleToRawLongBits(xd[14]));
460     expectEquals64(
461         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
462         Double.doubleToRawLongBits(xd[15]));
463 
464     System.out.println("passed");
465   }
466 
expectEquals32(int expected, int result)467   private static void expectEquals32(int expected, int result) {
468     if (expected != result) {
469       throw new Error("Expected: " + expected + ", found: " + result);
470     }
471   }
472 
expectEquals64(long expected, long result)473   private static void expectEquals64(long expected, long result) {
474     if (expected != result) {
475       throw new Error("Expected: " + expected + ", found: " + result);
476     }
477   }
478 
479   // We allow that an expected NaN result has become quiet.
expectEqualsNaN32(int expected, int result)480   private static void expectEqualsNaN32(int expected, int result) {
481     if (expected != result && (expected | SPQUIET) != result) {
482       if (!isDalvik) {
483         // If not on ART, relax the expected value more towards just
484         // "spec compliance" and allow sign bit to remain set for NaN.
485         if (expected == (result & Integer.MAX_VALUE)) {
486           return;
487         }
488       }
489       throw new Error("Expected: 0x" + Integer.toHexString(expected)
490           + ", found: 0x" + Integer.toHexString(result));
491     }
492   }
493 
494   // We allow that an expected NaN result has become quiet.
expectEqualsNaN64(long expected, long result)495   private static void expectEqualsNaN64(long expected, long result) {
496     if (expected != result && (expected | DPQUIET) != result) {
497       if (!isDalvik) {
498         // If not on ART, relax the expected value more towards just
499         // "spec compliance" and allow sign bit to remain set for NaN.
500         if (expected == (result & Long.MAX_VALUE)) {
501           return;
502         }
503       }
504       throw new Error("Expected: 0x" + Long.toHexString(expected)
505           + ", found: 0x" + Long.toHexString(result));
506     }
507   }
508 }
509