• 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 ABS vectorization.
19  */
20 public class Main {
21 
22   private static final int SPQUIET = 1 << 22;
23   private static final long DPQUIET = 1L << 51;
24 
25   /// CHECK-START: void Main.doitInt(int[]) loop_optimization (before)
26   /// CHECK-DAG: Phi                                       loop:<<Loop:B\d+>> outer_loop:none
27   /// CHECK-DAG: ArrayGet                                  loop:<<Loop>>      outer_loop:none
28   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>>      outer_loop:none
29   /// CHECK-DAG: ArraySet                                  loop:<<Loop>>      outer_loop:none
30   //
31   /// CHECK-START-ARM64: void Main.doitInt(int[]) loop_optimization (after)
32   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
33   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
34   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
35   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
36   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
37   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
38   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
39   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
40   //
41   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
doitInt(int[] x)42   private static void doitInt(int[] x) {
43     for (int i = 0; i < x.length; i++) {
44       x[i] = Math.abs(x[i]);
45     }
46   }
47 
48   /// CHECK-START: void Main.doitLong(long[]) loop_optimization (before)
49   /// CHECK-DAG: Phi                                        loop:<<Loop:B\d+>> outer_loop:none
50   /// CHECK-DAG: ArrayGet                                   loop:<<Loop>>      outer_loop:none
51   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsLong loop:<<Loop>>      outer_loop:none
52   /// CHECK-DAG: ArraySet                                   loop:<<Loop>>      outer_loop:none
53   //
54   /// CHECK-START-ARM64: void Main.doitLong(long[]) loop_optimization (after)
55   //
56   // TODO: Not supported yet.
doitLong(long[] x)57   private static void doitLong(long[] x) {
58     for (int i = 0; i < x.length; i++) {
59       x[i] = Math.abs(x[i]);
60     }
61   }
62 
63   /// CHECK-START: void Main.doitFloat(float[]) loop_optimization (before)
64   /// CHECK-DAG: Phi                                         loop:<<Loop:B\d+>> outer_loop:none
65   /// CHECK-DAG: ArrayGet                                    loop:<<Loop>>      outer_loop:none
66   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop>>      outer_loop:none
67   /// CHECK-DAG: ArraySet                                     loop:<<Loop>>      outer_loop:none
68   //
69   /// CHECK-START-ARM64: void Main.doitFloat(float[]) loop_optimization (after)
70   /// CHECK-DAG: Phi                                         loop:<<Loop1:B\d+>> outer_loop:none
71   /// CHECK-DAG: VecLoad                                     loop:<<Loop1>>      outer_loop:none
72   /// CHECK-DAG: VecAbs                                      loop:<<Loop1>>      outer_loop:none
73   /// CHECK-DAG: VecStore                                    loop:<<Loop1>>      outer_loop:none
74   /// CHECK-DAG: Phi                                         loop:<<Loop2:B\d+>> outer_loop:none
75   /// CHECK-DAG: ArrayGet                                    loop:<<Loop2>>      outer_loop:none
76   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop2>>      outer_loop:none
77   /// CHECK-DAG: ArraySet                                    loop:<<Loop2>>      outer_loop:none
78   //
79   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
doitFloat(float[] x)80   private static void doitFloat(float[] x) {
81     for (int i = 0; i < x.length; i++) {
82       x[i] = Math.abs(x[i]);
83     }
84   }
85 
86   /// CHECK-START: void Main.doitDouble(double[]) loop_optimization (before)
87   /// CHECK-DAG: Phi                                          loop:<<Loop:B\d+>> outer_loop:none
88   /// CHECK-DAG: ArrayGet                                     loop:<<Loop>>      outer_loop:none
89   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsDouble loop:<<Loop>>      outer_loop:none
90   /// CHECK-DAG: ArraySet                                     loop:<<Loop>>      outer_loop:none
91   //
92   /// CHECK-START-ARM64: void Main.doitDouble(double[]) loop_optimization (after)
93   //
94   // TODO: Not supported yet.
doitDouble(double[] x)95   private static void doitDouble(double[] x) {
96     for (int i = 0; i < x.length; i++) {
97       x[i] = Math.abs(x[i]);
98     }
99   }
100 
main(String[] args)101   public static void main(String[] args) {
102     // Set up minint32, maxint32 and some others.
103     int[] xi = new int[8];
104     xi[0] = 0x80000000;
105     xi[1] = 0x7fffffff;
106     xi[2] = 0x80000001;
107     xi[3] = -13;
108     xi[4] = -1;
109     xi[5] = 0;
110     xi[6] = 1;
111     xi[7] = 999;
112     doitInt(xi);
113     expectEquals32(0x80000000, xi[0]);
114     expectEquals32(0x7fffffff, xi[1]);
115     expectEquals32(0x7fffffff, xi[2]);
116     expectEquals32(13, xi[3]);
117     expectEquals32(1, xi[4]);
118     expectEquals32(0, xi[5]);
119     expectEquals32(1, xi[6]);
120     expectEquals32(999, xi[7]);
121 
122     // Set up minint64, maxint64 and some others.
123     long[] xl = new long[8];
124     xl[0] = 0x8000000000000000L;
125     xl[1] = 0x7fffffffffffffffL;
126     xl[2] = 0x8000000000000001L;
127     xl[3] = -13;
128     xl[4] = -1;
129     xl[5] = 0;
130     xl[6] = 1;
131     xl[7] = 999;
132     doitLong(xl);
133     expectEquals64(0x8000000000000000L, xl[0]);
134     expectEquals64(0x7fffffffffffffffL, xl[1]);
135     expectEquals64(0x7fffffffffffffffL, xl[2]);
136     expectEquals64(13, xl[3]);
137     expectEquals64(1, xl[4]);
138     expectEquals64(0, xl[5]);
139     expectEquals64(1, xl[6]);
140     expectEquals64(999, xl[7]);
141 
142     // Set up float NaN and some others.
143     float[] xf = new float[16];
144     xf[0] = Float.intBitsToFloat(0x7f800001);
145     xf[1] = Float.intBitsToFloat(0x7fa00000);
146     xf[2] = Float.intBitsToFloat(0x7fc00000);
147     xf[3] = Float.intBitsToFloat(0x7fffffff);
148     xf[4] = Float.intBitsToFloat(0xff800001);
149     xf[5] = Float.intBitsToFloat(0xffa00000);
150     xf[6] = Float.intBitsToFloat(0xffc00000);
151     xf[7] = Float.intBitsToFloat(0xffffffff);
152     xf[8] = Float.NEGATIVE_INFINITY;
153     xf[9] = -99.2f;
154     xf[10] = -1.0f;
155     xf[11] = -0.0f;
156     xf[12] = +0.0f;
157     xf[13] = +1.0f;
158     xf[14] = +99.2f;
159     xf[15] = Float.POSITIVE_INFINITY;
160     doitFloat(xf);
161     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[0]));
162     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[1]));
163     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[2]));
164     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[3]));
165     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[4]));
166     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[5]));
167     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[6]));
168     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[7]));
169     expectEquals32(
170         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
171         Float.floatToRawIntBits(xf[8]));
172     expectEquals32(
173         Float.floatToRawIntBits(99.2f),
174         Float.floatToRawIntBits(xf[9]));
175     expectEquals32(
176         Float.floatToRawIntBits(1.0f),
177         Float.floatToRawIntBits(xf[10]));
178     expectEquals32(0, Float.floatToRawIntBits(xf[11]));
179     expectEquals32(0, Float.floatToRawIntBits(xf[12]));
180     expectEquals32(
181         Float.floatToRawIntBits(1.0f),
182         Float.floatToRawIntBits(xf[13]));
183     expectEquals32(
184         Float.floatToRawIntBits(99.2f),
185         Float.floatToRawIntBits(xf[14]));
186     expectEquals32(
187         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
188         Float.floatToRawIntBits(xf[15]));
189 
190     // Set up double NaN and some others.
191     double[] xd = new double[16];
192     xd[0] = Double.longBitsToDouble(0x7ff0000000000001L);
193     xd[1] = Double.longBitsToDouble(0x7ff4000000000000L);
194     xd[2] = Double.longBitsToDouble(0x7ff8000000000000L);
195     xd[3] = Double.longBitsToDouble(0x7fffffffffffffffL);
196     xd[4] = Double.longBitsToDouble(0xfff0000000000001L);
197     xd[5] = Double.longBitsToDouble(0xfff4000000000000L);
198     xd[6] = Double.longBitsToDouble(0xfff8000000000000L);
199     xd[7] = Double.longBitsToDouble(0xffffffffffffffffL);
200     xd[8] = Double.NEGATIVE_INFINITY;
201     xd[9] = -99.2f;
202     xd[10] = -1.0f;
203     xd[11] = -0.0f;
204     xd[12] = +0.0f;
205     xd[13] = +1.0f;
206     xd[14] = +99.2f;
207     xd[15] = Double.POSITIVE_INFINITY;
208     doitDouble(xd);
209     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[0]));
210     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[1]));
211     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[2]));
212     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[3]));
213     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[4]));
214     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[5]));
215     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[6]));
216     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[7]));
217     expectEquals64(
218         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
219         Double.doubleToRawLongBits(xd[8]));
220     expectEquals64(
221         Double.doubleToRawLongBits(99.2f),
222         Double.doubleToRawLongBits(xd[9]));
223     expectEquals64(
224         Double.doubleToRawLongBits(1.0f),
225         Double.doubleToRawLongBits(xd[10]));
226     expectEquals64(0, Double.doubleToRawLongBits(xd[11]));
227     expectEquals64(0, Double.doubleToRawLongBits(xd[12]));
228     expectEquals64(
229         Double.doubleToRawLongBits(1.0f),
230         Double.doubleToRawLongBits(xd[13]));
231     expectEquals64(
232         Double.doubleToRawLongBits(99.2f),
233         Double.doubleToRawLongBits(xd[14]));
234     expectEquals64(
235         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
236         Double.doubleToRawLongBits(xd[15]));
237 
238     System.out.println("passed");
239   }
240 
expectEquals32(int expected, int result)241   private static void expectEquals32(int expected, int result) {
242     if (expected != result) {
243       throw new Error("Expected: " + expected + ", found: " + result);
244     }
245   }
246 
expectEquals64(long expected, long result)247   private static void expectEquals64(long expected, long result) {
248     if (expected != result) {
249       throw new Error("Expected: " + expected + ", found: " + result);
250     }
251   }
252 
253   // We allow that an expected NaN result has become quiet.
expectEqualsNaN32(int expected, int result)254   private static void expectEqualsNaN32(int expected, int result) {
255     if (expected != result && (expected | SPQUIET) != result) {
256       throw new Error("Expected: 0x" + Integer.toHexString(expected)
257           + ", found: 0x" + Integer.toHexString(result));
258     }
259   }
260 
261   // We allow that an expected NaN result has become quiet.
expectEqualsNaN64(long expected, long result)262   private static void expectEqualsNaN64(long expected, long result) {
263     if (expected != result && (expected | DPQUIET) != result) {
264       throw new Error("Expected: 0x" + Long.toHexString(expected)
265           + ", found: 0x" + Long.toHexString(result));
266     }
267   }
268 }
269