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