• 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  * Functional tests for SIMD vectorization.
19  */
20 public class Main {
21 
22   static byte[] a;
23 
24   //
25   // Arithmetic operations.
26   //
27 
28   /// CHECK-START: void Main.add(int) 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: ArraySet loop:<<Loop>>      outer_loop:none
32   //
33   /// CHECK-START-ARM64: void Main.add(int) loop_optimization (after)
34   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
35   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
36   /// CHECK-DAG: VecAdd   loop:<<Loop>>      outer_loop:none
37   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
add(int x)38   static void add(int x) {
39     for (int i = 0; i < 128; i++)
40       a[i] += x;
41   }
42 
43   /// CHECK-START: void Main.sub(int) loop_optimization (before)
44   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
45   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
46   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
47   //
48   /// CHECK-START-ARM64: void Main.sub(int) loop_optimization (after)
49   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
50   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
51   /// CHECK-DAG: VecSub   loop:<<Loop>>      outer_loop:none
52   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
sub(int x)53   static void sub(int x) {
54     for (int i = 0; i < 128; i++)
55       a[i] -= x;
56   }
57 
58   /// CHECK-START: void Main.mul(int) loop_optimization (before)
59   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
60   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
61   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
62   //
63   /// CHECK-START-ARM64: void Main.mul(int) loop_optimization (after)
64   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
65   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
66   /// CHECK-DAG: VecMul   loop:<<Loop>>      outer_loop:none
67   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
mul(int x)68   static void mul(int x) {
69     for (int i = 0; i < 128; i++)
70       a[i] *= x;
71   }
72 
73   /// CHECK-START: void Main.div(int) loop_optimization (before)
74   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
75   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
76   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
77   //
78   /// CHECK-START: void Main.div(int) loop_optimization (after)
79   //
80   //  Not supported on any architecture.
81   //
div(int x)82   static void div(int x) {
83     for (int i = 0; i < 128; i++)
84       a[i] /= x;
85   }
86 
87   /// CHECK-START: void Main.neg() loop_optimization (before)
88   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
89   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
90   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
91   //
92   /// CHECK-START-ARM64: void Main.neg() loop_optimization (after)
93   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
94   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
95   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
96   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
neg()97   static void neg() {
98     for (int i = 0; i < 128; i++)
99       a[i] = (byte) -a[i];
100   }
101 
102   /// CHECK-START: void Main.not() loop_optimization (before)
103   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
104   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
105   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
106   //
107   /// CHECK-START-ARM64: void Main.not() loop_optimization (after)
108   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
109   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
110   /// CHECK-DAG: VecNot   loop:<<Loop>>      outer_loop:none
111   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
not()112   static void not() {
113     for (int i = 0; i < 128; i++)
114       a[i] = (byte) ~a[i];
115   }
116 
117   /// CHECK-START: void Main.shl4() loop_optimization (before)
118   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
119   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
120   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
121   //
122   /// CHECK-START-ARM64: void Main.shl4() loop_optimization (after)
123   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
124   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
125   /// CHECK-DAG: VecShl   loop:<<Loop>>      outer_loop:none
126   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
shl4()127   static void shl4() {
128     for (int i = 0; i < 128; i++)
129       a[i] <<= 4;
130   }
131 
132   /// CHECK-START: void Main.sar2() loop_optimization (before)
133   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
134   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
135   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
136   //
137   /// CHECK-START-ARM64: void Main.sar2() loop_optimization (after)
138   //
139   // TODO: fill in when supported
sar2()140   static void sar2() {
141     for (int i = 0; i < 128; i++)
142       a[i] >>= 2;
143   }
144 
145   /// CHECK-START: void Main.shr2() loop_optimization (before)
146   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
147   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
148   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
149   //
150   /// CHECK-START-ARM64: void Main.shr2() loop_optimization (after)
151   //
152   // TODO: fill in when supported
shr2()153   static void shr2() {
154     for (int i = 0; i < 128; i++)
155       a[i] >>>= 2;
156   }
157 
158   //
159   // Shift sanity.
160   //
161 
sar31()162   static void sar31() {
163     for (int i = 0; i < 128; i++)
164       a[i] >>= 31;
165   }
166 
shr31()167   static void shr31() {
168     for (int i = 0; i < 128; i++)
169       a[i] >>>= 31;
170   }
171 
shr32()172   static void shr32() {
173     for (int i = 0; i < 128; i++)
174       a[i] >>>= 32;  // 0, since & 31
175   }
176 
shr33()177   static void shr33() {
178     for (int i = 0; i < 128; i++)
179       a[i] >>>= 33;  // 1, since & 31
180   }
181 
shl9()182   static void shl9() {
183     for (int i = 0; i < 128; i++)
184       a[i] <<= 9;  // yields all-zeros
185   }
186 
187   //
188   // Loop bounds.
189   //
190 
bounds()191   static void bounds() {
192     for (int i = 1; i < 127; i++)
193       a[i] += 11;
194   }
195 
196   //
197   // Test Driver.
198   //
199 
main(String[] args)200   public static void main(String[] args) {
201     // Set up.
202     a = new byte[128];
203     for (int i = 0; i < 128; i++) {
204       a[i] = (byte) i;
205     }
206     // Arithmetic operations.
207     add(2);
208     for (int i = 0; i < 128; i++) {
209       expectEquals((byte)(i + 2), a[i], "add");
210     }
211     sub(2);
212     for (int i = 0; i < 128; i++) {
213       expectEquals(i, a[i], "sub");
214     }
215     mul(2);
216     for (int i = 0; i < 128; i++) {
217       expectEquals((byte)(i + i), a[i], "mul");
218     }
219     div(2);
220     for (int i = 0; i < 128; i++) {
221       expectEquals(((byte)(i + i)) >> 1, a[i], "div");
222       a[i] = (byte) i;  // undo arithmetic wrap-around effects
223     }
224     neg();
225     for (int i = 0; i < 128; i++) {
226       expectEquals(-i, a[i], "neg");
227     }
228     // Loop bounds.
229     bounds();
230     expectEquals(0, a[0], "bounds0");
231     for (int i = 1; i < 127; i++) {
232       expectEquals(11 - i, a[i], "bounds");
233     }
234     expectEquals(-127, a[127], "bounds127");
235     // Shifts.
236     for (int i = 0; i < 128; i++) {
237       a[i] = (byte) 0xff;
238     }
239     shl4();
240     for (int i = 0; i < 128; i++) {
241       expectEquals((byte) 0xf0, a[i], "shl4");
242     }
243     sar2();
244     for (int i = 0; i < 128; i++) {
245       expectEquals((byte) 0xfc, a[i], "sar2");
246     }
247     shr2();
248     for (int i = 0; i < 128; i++) {
249       expectEquals((byte) 0xff, a[i], "shr2");  // sic!
250     }
251     sar31();
252     for (int i = 0; i < 128; i++) {
253       expectEquals((byte) 0xff, a[i], "sar31");
254     }
255     shr31();
256     for (int i = 0; i < 128; i++) {
257       expectEquals(0x01, a[i], "shr31");
258       a[i] = (byte) 0x12;  // reset
259     }
260     shr32();
261     for (int i = 0; i < 128; i++) {
262       expectEquals((byte) 0x12, a[i], "shr32");
263     }
264     shr33();
265     for (int i = 0; i < 128; i++) {
266       expectEquals((byte) 0x09, a[i], "shr33");
267     }
268     shl9();
269     for (int i = 0; i < 128; i++) {
270       expectEquals((byte) 0x00, a[i], "shl9");
271       a[i] = (byte) 0xf0;  // reset
272     }
273     not();
274     for (int i = 0; i < 128; i++) {
275       expectEquals((byte) 0x0f, a[i], "not");
276     }
277     // Done.
278     System.out.println("passed");
279   }
280 
expectEquals(int expected, int result, String action)281   private static void expectEquals(int expected, int result, String action) {
282     if (expected != result) {
283       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
284     }
285   }
286 }
287