• 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 long[] a;
23 
24   //
25   // Arithmetic operations.
26   //
27 
28   /// CHECK-START: void Main.add(long) 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(long) 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(long x)38   static void add(long x) {
39     for (int i = 0; i < 128; i++)
40       a[i] += x;
41   }
42 
43   /// CHECK-START: void Main.sub(long) 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(long) 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(long x)53   static void sub(long x) {
54     for (int i = 0; i < 128; i++)
55       a[i] -= x;
56   }
57 
58   /// CHECK-START: void Main.mul(long) 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   //  Not supported for longs.
64   /// CHECK-START-ARM64: void Main.mul(long) loop_optimization (after)
65   /// CHECK-NOT: VecMul
mul(long x)66   static void mul(long x) {
67     for (int i = 0; i < 128; i++)
68       a[i] *= x;
69   }
70 
71   /// CHECK-START: void Main.div(long) loop_optimization (before)
72   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
73   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
74   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
75   //
76   /// CHECK-START: void Main.div(long) loop_optimization (after)
77   //
78   //  Not supported on any architecture.
79   //
div(long x)80   static void div(long x) {
81     for (int i = 0; i < 128; i++)
82       a[i] /= x;
83   }
84 
85   /// CHECK-START: void Main.neg() loop_optimization (before)
86   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
87   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
88   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
89   //
90   /// CHECK-START-ARM64: void Main.neg() loop_optimization (after)
91   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
92   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
93   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
94   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
neg()95   static void neg() {
96     for (int i = 0; i < 128; i++)
97       a[i] = -a[i];
98   }
99 
100   /// CHECK-START: void Main.not() loop_optimization (before)
101   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
102   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
103   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
104   //
105   /// CHECK-START-ARM64: void Main.not() loop_optimization (after)
106   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
107   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
108   /// CHECK-DAG: VecNot   loop:<<Loop>>      outer_loop:none
109   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
not()110   static void not() {
111     for (int i = 0; i < 128; i++)
112       a[i] = ~a[i];
113   }
114 
115   /// CHECK-START: void Main.shl4() loop_optimization (before)
116   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
117   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
118   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
119   //
120   /// CHECK-START-ARM64: void Main.shl4() loop_optimization (after)
121   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
122   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
123   /// CHECK-DAG: VecShl   loop:<<Loop>>      outer_loop:none
124   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
shl4()125   static void shl4() {
126     for (int i = 0; i < 128; i++)
127       a[i] <<= 4;
128   }
129 
130   /// CHECK-START: void Main.sar2() loop_optimization (before)
131   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
132   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
133   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
134   //
135   /// CHECK-START-ARM64: void Main.sar2() loop_optimization (after)
136   //
137   // TODO: fill in when supported
sar2()138   static void sar2() {
139     for (int i = 0; i < 128; i++)
140       a[i] >>= 2;
141   }
142 
143   /// CHECK-START: void Main.shr2() loop_optimization (before)
144   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
145   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
146   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
147   //
148   /// CHECK-START-ARM64: void Main.shr2() loop_optimization (after)
149   //
150   // TODO: fill in when supported
shr2()151   static void shr2() {
152     for (int i = 0; i < 128; i++)
153       a[i] >>>= 2;
154   }
155 
156   //
157   // Shift sanity.
158   //
159 
shr64()160   static void shr64() {
161     for (int i = 0; i < 128; i++)
162       a[i] >>>= 64;  // 0, since & 63
163   }
164 
shr65()165   static void shr65() {
166     for (int i = 0; i < 128; i++)
167       a[i] >>>= 65;  // 1, since & 63
168   }
169 
170   //
171   // Loop bounds.
172   //
173 
bounds()174   static void bounds() {
175     for (int i = 1; i < 127; i++)
176       a[i] += 11;
177   }
178 
179   //
180   // Test Driver.
181   //
182 
main(String[] args)183   public static void main(String[] args) {
184     // Set up.
185     a = new long[128];
186     for (int i = 0; i < 128; i++) {
187       a[i] = i;
188     }
189     // Arithmetic operations.
190     add(2L);
191     for (int i = 0; i < 128; i++) {
192       expectEquals(i + 2, a[i], "add");
193     }
194     sub(2L);
195     for (int i = 0; i < 128; i++) {
196       expectEquals(i, a[i], "sub");
197     }
198     mul(2L);
199     for (int i = 0; i < 128; i++) {
200       expectEquals(i + i, a[i], "mul");
201     }
202     div(2L);
203     for (int i = 0; i < 128; i++) {
204       expectEquals(i, a[i], "div");
205     }
206     neg();
207     for (int i = 0; i < 128; i++) {
208       expectEquals(-i, a[i], "neg");
209     }
210     // Loop bounds.
211     bounds();
212     expectEquals(0, a[0], "bounds0");
213     for (int i = 1; i < 127; i++) {
214       expectEquals(11 - i, a[i], "bounds");
215     }
216     expectEquals(-127, a[127], "bounds127");
217     // Shifts.
218     for (int i = 0; i < 128; i++) {
219       a[i] = 0xffffffffffffffffL;
220     }
221     shl4();
222     for (int i = 0; i < 128; i++) {
223       expectEquals(0xfffffffffffffff0L, a[i], "shl4");
224     }
225     sar2();
226     for (int i = 0; i < 128; i++) {
227       expectEquals(0xfffffffffffffffcL, a[i], "sar2");
228     }
229     shr2();
230     for (int i = 0; i < 128; i++) {
231       expectEquals(0x3fffffffffffffffL, a[i], "shr2");
232     }
233     shr64();
234     for (int i = 0; i < 128; i++) {
235       expectEquals(0x3fffffffffffffffL, a[i], "shr64");
236     }
237     shr65();
238     for (int i = 0; i < 128; i++) {
239       expectEquals(0x1fffffffffffffffL, a[i], "shr65");
240     }
241     not();
242     for (int i = 0; i < 128; i++) {
243       expectEquals(0xe000000000000000L, a[i], "not");
244     }
245     // Done.
246     System.out.println("passed");
247   }
248 
expectEquals(long expected, long result, String action)249   private static void expectEquals(long expected, long result, String action) {
250     if (expected != result) {
251       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
252     }
253   }
254 }
255