1 /*
2  * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package compiler.vectorapi;
25 
26 import java.util.Random;
27 import java.util.Arrays;
28 
29 import jdk.incubator.vector.*;
30 
31 /**
32  * @test
33  * @bug 8261142
34  * @summary AArch64: Incorrect instruction encoding when right-shifting vectors with shift amount equals to the element width
35  * @modules jdk.incubator.vector
36  *
37  * @run main/othervm -XX:CompileCommand=print,compiler/vectorapi/TestVectorShiftImm.shift*
38  *                   -XX:-TieredCompilation -Dvlen=64 compiler.vectorapi.TestVectorShiftImm
39  * @run main/othervm -XX:CompileCommand=print,compiler/vectorapi/TestVectorShiftImm.shift*
40  *                   -XX:-TieredCompilation -Dvlen=128 compiler.vectorapi.TestVectorShiftImm
41  */
42 
43 public class TestVectorShiftImm {
44     private static final int ARR_LEN = 16;
45     private static final int NUM_ITERS = 100000;
46 
47     private static final int NUM_OPS          = 5;
48     private static final int ACCUMULATE_OP_S  = 3;
49     private static final int MAX_TESTS_PER_OP = 7;
50     private static final int VLENS            = 2;
51 
52     private static byte[]  bytesA,    bytesB;
53     private static short[] shortsA,   shortsB;
54     private static int[]   integersA, integersB;
55     private static long[]  longsA,    longsB;
56 
57     private static byte  tBytes[][],    gBytes[][];
58     private static short tShorts[][],   gShorts[][];
59     private static int   tIntegers[][], gIntegers[][];
60     private static long  tLongs[][],    gLongs[][];
61 
62     private static Random r = new Random(32781);
63 
64     static final VectorSpecies<Byte> byte64SPECIES  = ByteVector.SPECIES_64;
65     static final VectorSpecies<Byte> byte128SPECIES = ByteVector.SPECIES_128;
66 
67     static final VectorSpecies<Short> short64SPECIES  = ShortVector.SPECIES_64;
68     static final VectorSpecies<Short> short128SPECIES = ShortVector.SPECIES_128;
69 
70     static final VectorSpecies<Integer> integer64SPECIES  = IntVector.SPECIES_64;
71     static final VectorSpecies<Integer> integer128SPECIES = IntVector.SPECIES_128;
72 
73     static final VectorSpecies<Long> long128SPECIES = LongVector.SPECIES_128;
74 
75     static String[] opNames = {"LSHL", "ASHR", "LSHR", "ASHR_AND_ACCUMULATE", "LSHR_AND_ACCUMULATE"};
76 
77     static boolean allTestsPassed = true;
78     static StringBuilder errMsg = new StringBuilder();
79 
main(String args[])80     public static void main(String args[]) {
81 
82         int vlen = Integer.parseInt(System.getProperty("vlen", ""));
83 
84         test_init();
85 
86         if (vlen == 64) {
87             test_vlen64();
88         }
89 
90         if(vlen == 128) {
91             test_vlen128();
92         }
93 
94         if (allTestsPassed) {
95             System.out.println("Test PASSED");
96         } else {
97             throw new RuntimeException("Test Failed, failed tests:\n" + errMsg.toString());
98         }
99     }
100 
test_vlen64()101     static void test_vlen64() {
102         for (int i = 0; i < NUM_ITERS; i++) {
103             shift_and_accumulate(tBytes, true, byte64SPECIES, 64);
104             shift_and_accumulate(tShorts, true, short64SPECIES, 64);
105             shift_and_accumulate(tIntegers, true, integer64SPECIES, 64);
106 
107             shift(tBytes, true, byte64SPECIES, 64);
108             shift(tShorts, true, short64SPECIES, 64);
109             shift(tIntegers, true, integer64SPECIES, 64);
110         }
111     }
112 
test_vlen128()113     static void test_vlen128() {
114         for (int i = 0; i < NUM_ITERS; i++) {
115             shift_and_accumulate(tBytes, true, byte128SPECIES, 128);
116             shift_and_accumulate(tShorts, true, short128SPECIES, 128);
117             shift_and_accumulate(tIntegers, true, integer128SPECIES, 128);
118             shift_and_accumulate(tLongs, true, long128SPECIES, 128);
119 
120             shift(tBytes, true, byte128SPECIES, 128);
121             shift(tShorts, true, short128SPECIES, 128);
122             shift(tIntegers, true, integer128SPECIES, 128);
123             shift(tLongs, true, long128SPECIES, 128);
124         }
125     }
126 
127     /**
128      * Tests for type byte.
129      */
130 
shift_with_op(VectorOperators.Binary op, ByteVector vbb, byte arr[][], int end, int ind)131     static int shift_with_op(VectorOperators.Binary op, ByteVector vbb,
132                              byte arr[][], int end, int ind) {
133         vbb.lanewise(op, 0).intoArray(arr[end++], ind);
134         vbb.lanewise(op, 1).intoArray(arr[end++], ind);
135         vbb.lanewise(op, 8).intoArray(arr[end++], ind);
136         vbb.lanewise(op, 13).intoArray(arr[end++], ind);
137         vbb.lanewise(op, 16).intoArray(arr[end++], ind);
138         vbb.lanewise(op, 19).intoArray(arr[end++], ind);
139         vbb.lanewise(op, 24).intoArray(arr[end++], ind);
140         return end;
141     }
142 
shift_with_op_and_add(VectorOperators.Binary op, ByteVector vba, ByteVector vbb, byte arr[][], int end, int ind)143     static int shift_with_op_and_add(VectorOperators.Binary op,
144                                      ByteVector vba, ByteVector vbb,
145                                      byte arr[][], int end, int ind) {
146         vba.add(vbb.lanewise(op, 0)).intoArray(arr[end++], ind);
147         vba.add(vbb.lanewise(op, 1)).intoArray(arr[end++], ind);
148         vba.add(vbb.lanewise(op, 8)).intoArray(arr[end++], ind);
149         vba.add(vbb.lanewise(op, 13)).intoArray(arr[end++], ind);
150         vba.add(vbb.lanewise(op, 16)).intoArray(arr[end++], ind);
151         vba.add(vbb.lanewise(op, 19)).intoArray(arr[end++], ind);
152         vba.add(vbb.lanewise(op, 24)).intoArray(arr[end++], ind);
153         return end;
154     }
155 
shift(byte arrBytes[][], boolean verify, VectorSpecies<Byte> vSpecies, int vlen)156     static void shift(byte arrBytes[][], boolean verify,
157                       VectorSpecies<Byte> vSpecies, int vlen) {
158         int start = vlen / 128 * NUM_OPS * MAX_TESTS_PER_OP, end = 0;
159 
160         for (int i = 0; i < ARR_LEN; i += vlen / 8) {
161             end = start;
162             ByteVector vbb = ByteVector.fromArray(vSpecies, bytesB, i);
163             end = shift_with_op(VectorOperators.LSHL, vbb, arrBytes, end, i);
164             end = shift_with_op(VectorOperators.ASHR, vbb, arrBytes, end, i);
165             end = shift_with_op(VectorOperators.LSHR, vbb, arrBytes, end, i);
166         }
167 
168         if (verify) {
169             for (int i = start; i < end; i++) {
170                 assertTrue("BYTE", Arrays.equals(tBytes[i], gBytes[i]), i, vlen);
171             }
172         }
173     }
174 
shift_and_accumulate(byte arrBytes[][], boolean verify, VectorSpecies<Byte> vSpecies, int vlen)175     static void shift_and_accumulate(byte arrBytes[][], boolean verify,
176                                            VectorSpecies<Byte> vSpecies, int vlen) {
177         int start = (ACCUMULATE_OP_S + vlen / 128 * NUM_OPS) * MAX_TESTS_PER_OP, end = 0;
178 
179         for (int i = 0; i < ARR_LEN; i += vlen / 8) {
180             end = start;
181             ByteVector vba = ByteVector.fromArray(vSpecies, bytesA, i);
182             ByteVector vbb = ByteVector.fromArray(vSpecies, bytesB, i);
183             end = shift_with_op_and_add(VectorOperators.ASHR, vba, vbb, arrBytes, end, i);
184             end = shift_with_op_and_add(VectorOperators.LSHR, vba, vbb, arrBytes, end, i);
185         }
186 
187         if (verify) {
188             for (int i = start; i < end; i++) {
189                 assertTrue("BYTE", Arrays.equals(tBytes[i], gBytes[i]), i, vlen);
190             }
191         }
192     }
193 
194     /**
195      * Tests for type short.
196      */
197 
shift_with_op(VectorOperators.Binary op, ShortVector vbb, short arr[][], int end, int ind)198     static int shift_with_op(VectorOperators.Binary op, ShortVector vbb,
199                              short arr[][], int end, int ind) {
200         vbb.lanewise(op, 0).intoArray(arr[end++], ind);
201         vbb.lanewise(op, 9).intoArray(arr[end++], ind);
202         vbb.lanewise(op, 16).intoArray(arr[end++], ind);
203         vbb.lanewise(op, 27).intoArray(arr[end++], ind);
204         vbb.lanewise(op, 32).intoArray(arr[end++], ind);
205         vbb.lanewise(op, 43).intoArray(arr[end++], ind);
206         vbb.lanewise(op, 48).intoArray(arr[end++], ind);
207         return end;
208     }
209 
shift_with_op_and_add(VectorOperators.Binary op, ShortVector vba, ShortVector vbb, short arr[][], int end, int ind)210     static int shift_with_op_and_add(VectorOperators.Binary op,
211                                      ShortVector vba, ShortVector vbb,
212                                      short arr[][], int end, int ind) {
213         vba.add(vbb.lanewise(op, 0)).intoArray(arr[end++], ind);
214         vba.add(vbb.lanewise(op, 9)).intoArray(arr[end++], ind);
215         vba.add(vbb.lanewise(op, 16)).intoArray(arr[end++], ind);
216         vba.add(vbb.lanewise(op, 27)).intoArray(arr[end++], ind);
217         vba.add(vbb.lanewise(op, 32)).intoArray(arr[end++], ind);
218         vba.add(vbb.lanewise(op, 43)).intoArray(arr[end++], ind);
219         vba.add(vbb.lanewise(op, 48)).intoArray(arr[end++], ind);
220         return end;
221     }
222 
shift(short arrShorts[][], boolean verify, VectorSpecies<Short> vSpecies, int vlen)223     static void shift(short arrShorts[][], boolean verify,
224                       VectorSpecies<Short> vSpecies, int vlen) {
225         int start = vlen / 128 * NUM_OPS * MAX_TESTS_PER_OP, end = 0;
226 
227         for (int i = 0; i < ARR_LEN; i += vlen / 16) {
228             end = start;
229             ShortVector vbb = ShortVector.fromArray(vSpecies, shortsB, i);
230             end = shift_with_op(VectorOperators.LSHL, vbb, arrShorts, end, i);
231             end = shift_with_op(VectorOperators.ASHR, vbb, arrShorts, end, i);
232             end = shift_with_op(VectorOperators.LSHR, vbb, arrShorts, end, i);
233         }
234 
235         if (verify) {
236             for (int i = start; i < end; i++) {
237                 assertTrue("SHORT", Arrays.equals(tShorts[i], gShorts[i]), i, vlen);
238             }
239         }
240     }
241 
shift_and_accumulate(short arrShorts[][], boolean verify, VectorSpecies<Short> vSpecies, int vlen)242     static void shift_and_accumulate(short arrShorts[][], boolean verify,
243                                      VectorSpecies<Short> vSpecies, int vlen) {
244         int start = (ACCUMULATE_OP_S + vlen / 128 * NUM_OPS) * MAX_TESTS_PER_OP, end = 0;
245 
246         for (int i = 0; i < ARR_LEN; i += vlen / 16) {
247             end = start;
248             ShortVector vba = ShortVector.fromArray(vSpecies, shortsA, i);
249             ShortVector vbb = ShortVector.fromArray(vSpecies, shortsB, i);
250             end = shift_with_op_and_add(VectorOperators.ASHR, vba, vbb, arrShorts, end, i);
251             end = shift_with_op_and_add(VectorOperators.LSHR, vba, vbb, arrShorts, end, i);
252         }
253 
254         if (verify) {
255             for (int i = start; i < end; i++) {
256                 assertTrue("SHORT", Arrays.equals(tShorts[i], gShorts[i]), i, vlen);
257             }
258         }
259     }
260 
261     /**
262      * Tests for type int.
263      */
264 
shift_with_op(VectorOperators.Binary op, IntVector vbb, int arr[][], int end, int ind)265     static int shift_with_op(VectorOperators.Binary op, IntVector vbb,
266                              int arr[][], int end, int ind) {
267         vbb.lanewise(op, 0).intoArray(arr[end++], ind);
268         vbb.lanewise(op, 17).intoArray(arr[end++], ind);
269         vbb.lanewise(op, 32).intoArray(arr[end++], ind);
270         vbb.lanewise(op, 53).intoArray(arr[end++], ind);
271         vbb.lanewise(op, 64).intoArray(arr[end++], ind);
272         vbb.lanewise(op, 76).intoArray(arr[end++], ind);
273         vbb.lanewise(op, 96).intoArray(arr[end++], ind);
274         return end;
275     }
276 
shift_with_op_and_add(VectorOperators.Binary op, IntVector vba, IntVector vbb, int arr[][], int end, int ind)277     static int shift_with_op_and_add(VectorOperators.Binary op,
278                                      IntVector vba, IntVector vbb,
279                                      int arr[][], int end, int ind) {
280         vba.add(vbb.lanewise(op, 0)).intoArray(arr[end++], ind);
281         vba.add(vbb.lanewise(op, 17)).intoArray(arr[end++], ind);
282         vba.add(vbb.lanewise(op, 32)).intoArray(arr[end++], ind);
283         vba.add(vbb.lanewise(op, 53)).intoArray(arr[end++], ind);
284         vba.add(vbb.lanewise(op, 64)).intoArray(arr[end++], ind);
285         vba.add(vbb.lanewise(op, 76)).intoArray(arr[end++], ind);
286         vba.add(vbb.lanewise(op, 96)).intoArray(arr[end++], ind);
287         return end;
288     }
289 
shift(int arrIntegers[][], boolean verify, VectorSpecies<Integer> vSpecies, int vlen)290     static void shift(int arrIntegers[][], boolean verify,
291                       VectorSpecies<Integer> vSpecies, int vlen) {
292         int start = vlen / 128 * NUM_OPS * MAX_TESTS_PER_OP, end = 0;
293 
294         for (int i = 0; i < ARR_LEN; i += vlen / 32) {
295             end = start;
296             IntVector vbb = IntVector.fromArray(vSpecies, integersB, i);
297             end = shift_with_op(VectorOperators.LSHL, vbb, arrIntegers, end, i);
298             end = shift_with_op(VectorOperators.ASHR, vbb, arrIntegers, end, i);
299             end = shift_with_op(VectorOperators.LSHR, vbb, arrIntegers, end, i);
300         }
301 
302         if (verify) {
303             for (int i = start; i < end; i++) {
304                 assertTrue("INTEGER", Arrays.equals(tIntegers[i], gIntegers[i]), i, vlen);
305             }
306         }
307     }
308 
shift_and_accumulate(int arrIntegers[][], boolean verify, VectorSpecies<Integer> vSpecies, int vlen)309     static void shift_and_accumulate(int arrIntegers[][], boolean verify,
310                                      VectorSpecies<Integer> vSpecies, int vlen) {
311         int start = (ACCUMULATE_OP_S + vlen / 128 * NUM_OPS) * MAX_TESTS_PER_OP, end = 0;
312 
313         for (int i = 0; i < ARR_LEN; i += vlen / 32) {
314             end = start;
315             IntVector vba = IntVector.fromArray(vSpecies, integersA, i);
316             IntVector vbb = IntVector.fromArray(vSpecies, integersB, i);
317             end = shift_with_op_and_add(VectorOperators.ASHR, vba, vbb, arrIntegers, end, i);
318             end = shift_with_op_and_add(VectorOperators.LSHR, vba, vbb, arrIntegers, end, i);
319         }
320 
321         if (verify) {
322             for (int i = start; i < end; i++) {
323                 assertTrue("INTEGER", Arrays.equals(tIntegers[i], gIntegers[i]), i, vlen);
324             }
325         }
326     }
327 
328     /**
329      * Tests for type long.
330      */
331 
shift_with_op(VectorOperators.Binary op, LongVector vbb, long arr[][], int end, int ind)332     static int shift_with_op(VectorOperators.Binary op, LongVector vbb,
333                              long arr[][], int end, int ind) {
334         vbb.lanewise(op, 0).intoArray(arr[end++], ind);
335         vbb.lanewise(op, 37).intoArray(arr[end++], ind);
336         vbb.lanewise(op, 64).intoArray(arr[end++], ind);
337         vbb.lanewise(op, 99).intoArray(arr[end++], ind);
338         vbb.lanewise(op, 128).intoArray(arr[end++], ind);
339         vbb.lanewise(op, 157).intoArray(arr[end++], ind);
340         vbb.lanewise(op, 192).intoArray(arr[end++], ind);
341         return end;
342     }
343 
shift_with_op_and_add(VectorOperators.Binary op, LongVector vba, LongVector vbb, long arr[][], int end, int ind)344     static int shift_with_op_and_add(VectorOperators.Binary op,
345                                      LongVector vba, LongVector vbb,
346                                      long arr[][], int end, int ind) {
347         vba.add(vbb.lanewise(op, 0)).intoArray(arr[end++], ind);
348         vba.add(vbb.lanewise(op, 37)).intoArray(arr[end++], ind);
349         vba.add(vbb.lanewise(op, 64)).intoArray(arr[end++], ind);
350         vba.add(vbb.lanewise(op, 99)).intoArray(arr[end++], ind);
351         vba.add(vbb.lanewise(op, 128)).intoArray(arr[end++], ind);
352         vba.add(vbb.lanewise(op, 157)).intoArray(arr[end++], ind);
353         vba.add(vbb.lanewise(op, 192)).intoArray(arr[end++], ind);
354         return end;
355     }
356 
shift(long arrLongs[][], boolean verify, VectorSpecies<Long> vSpecies, int vlen)357     static void shift(long arrLongs[][], boolean verify,
358                       VectorSpecies<Long> vSpecies, int vlen) {
359         int start = vlen / 128 * NUM_OPS * MAX_TESTS_PER_OP, end = 0;
360 
361         for (int i = 0; i < ARR_LEN; i += vlen / 64) {
362             end = start;
363             LongVector vbb = LongVector.fromArray(vSpecies, longsB, i);
364             end = shift_with_op(VectorOperators.LSHL, vbb, arrLongs, end, i);
365             end = shift_with_op(VectorOperators.ASHR, vbb, arrLongs, end, i);
366             end = shift_with_op(VectorOperators.LSHR, vbb, arrLongs, end, i);
367         }
368 
369         if (verify) {
370             for (int i = start; i < end; i++) {
371                 assertTrue("LONG", Arrays.equals(tLongs[i], gLongs[i]), i, vlen);
372             }
373         }
374     }
375 
shift_and_accumulate(long arrLongs[][], boolean verify, VectorSpecies<Long> vSpecies, int vlen)376     static void shift_and_accumulate(long arrLongs[][], boolean verify,
377                                      VectorSpecies<Long> vSpecies, int vlen) {
378         int start = (ACCUMULATE_OP_S + vlen / 128 * NUM_OPS) * MAX_TESTS_PER_OP, end = 0;
379 
380         for (int i = 0; i < ARR_LEN; i += vlen / 64) {
381             end = start;
382             LongVector vba = LongVector.fromArray(vSpecies, longsA, i);
383             LongVector vbb = LongVector.fromArray(vSpecies, longsB, i);
384             end = shift_with_op_and_add(VectorOperators.ASHR, vba, vbb, arrLongs, end, i);
385             end = shift_with_op_and_add(VectorOperators.LSHR, vba, vbb, arrLongs, end, i);
386         }
387 
388         if (verify) {
389             for (int i = start; i < end; i++) {
390                 assertTrue("LONG", Arrays.equals(tLongs[i], gLongs[i]), i, vlen);
391             }
392         }
393     }
394 
test_init()395     static void test_init() {
396         int count = ARR_LEN;
397 
398         bytesA    = new byte[count];
399         shortsA   = new short[count];
400         integersA = new int[count];
401         longsA    = new long[count];
402 
403         bytesB    = new byte[count];
404         shortsB   = new short[count];
405         integersB = new int[count];
406         longsB    = new long[count];
407 
408         tBytes    = new byte[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
409         tShorts   = new short[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
410         tIntegers = new int[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
411         tLongs    = new long[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
412 
413         gBytes    = new byte[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
414         gShorts   = new short[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
415         gIntegers = new int[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
416         gLongs    = new long[VLENS * MAX_TESTS_PER_OP * NUM_OPS][count];
417 
418         for (int i = 0; i < count; i++) {
419             bytesA[i]    = (byte) r.nextInt();
420             shortsA[i]   = (short) r.nextInt();
421             integersA[i] = r.nextInt();
422             longsA[i]    = r.nextLong();
423 
424             bytesB[i]    = (byte) r.nextInt();
425             shortsB[i]   = (short) r.nextInt();
426             integersB[i] = r.nextInt();
427             longsB[i]    = r.nextLong();
428         }
429 
430         shift(gBytes, false, byte64SPECIES,  64);
431         shift(gBytes, false, byte128SPECIES, 128);
432         shift_and_accumulate(gBytes, false, byte64SPECIES,  64);
433         shift_and_accumulate(gBytes, false, byte128SPECIES, 128);
434 
435         shift(gShorts, false, short64SPECIES,  64);
436         shift(gShorts, false, short128SPECIES, 128);
437         shift_and_accumulate(gShorts, false, short64SPECIES,  64);
438         shift_and_accumulate(gShorts, false, short128SPECIES, 128);
439 
440         shift(gIntegers, false, integer64SPECIES,  64);
441         shift(gIntegers, false, integer128SPECIES, 128);
442         shift_and_accumulate(gIntegers, false, integer64SPECIES,  64);
443         shift_and_accumulate(gIntegers, false, integer128SPECIES, 128);
444 
445         shift(gLongs, false, long128SPECIES, 128);
446         shift_and_accumulate(gLongs, false, long128SPECIES, 128);
447     }
448 
assertTrue(String type, boolean okay, int i, int vlen)449     static void assertTrue(String type, boolean okay, int i, int vlen) {
450         int op = i % (MAX_TESTS_PER_OP * NUM_OPS) / MAX_TESTS_PER_OP;
451         if (!okay) {
452             allTestsPassed = false;
453             if (!errMsg.toString().contains("type " + type + " index " + i)) {
454                 errMsg.append("type " + type + " index " + i + ", operation " + opNames[op] + ", vector length "+ vlen + ".\n");
455             }
456         }
457     }
458 }
459