/* * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 8260585 * @summary AArch64: Wrong code generated for shifting right and accumulating four unsigned short integers. * * @run main/othervm compiler.c2.TestShiftRightAndAccumulate * @run main/othervm -Xcomp compiler.c2.TestShiftRightAndAccumulate */ /** * @test * @bug 8260585 * @summary AArch64: Wrong code generated for shifting right and accumulating four unsigned short integers. * @requires vm.compiler2.enabled * * @run main/othervm -XX:-SuperWordLoopUnrollAnalysis compiler.c2.TestShiftRightAndAccumulate */ package compiler.c2; import java.util.Random; import java.util.Arrays; public class TestShiftRightAndAccumulate { private static final int SMALL_LEN = 16; private static final int LARGE_LEN = 1000; private static final int NUM_ITERS = 200000; private static final int MAX_TESTS = 10; private static final int SMALL_INTS_LEN = 3; private static final int SMALL_BYTES_LEN = 80; private static byte[] bytesA, bytesB, bytesC, bytesD; private static short[] shortsA, shortsB, shortsC, shortsD; private static char[] charsA, charsB, charsC; private static int[] intsA, intsB, intsC; private static long[] longsA, longsB, longsC; private static byte gBytes[][]; private static short gShorts[][]; private static char gChars[][]; private static int gInts[][]; private static long gLongs[][]; private static Random r = new Random(32781); public static void main(String args[]) { test_init(SMALL_LEN); for (int it = 0; it < NUM_ITERS; it++) { test_bytes(); test_shorts(); test_chars(); test_ints(); test_longs(); } test_init(LARGE_LEN); for (int it = 0; it < NUM_ITERS; it++) { test_bytes(); test_shorts(); test_chars(); test_ints(); test_longs(); } System.out.println("Test PASSED"); } static void test_bytes() { for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >> 1)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[0])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >> 8)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[1])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 1])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >> 13)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[2])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 2])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >> 19)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[3])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 3])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >>> 1)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[4])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 4])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >>> 8)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[5])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 5])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >>> 13)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[6])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 6])); for (int i = 0; i < bytesC.length; i++) { bytesC[i] = (byte) (bytesA[i] + (bytesB[i] >>> 19)); bytesD[i] = (byte) (bytesA[i] + bytesB[i]); } assertTrue(Arrays.equals(bytesC, gBytes[7])); assertTrue(Arrays.equals(bytesD, gBytes[MAX_TESTS + 7])); } static void test_shorts() { for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >> 5)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[0])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >> 16)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[1])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 1])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >> 23)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[2])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 2])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >> 35)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[3])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 3])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >>> 7)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[4])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 4])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >>> 16)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[5])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 5])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >>> 23)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[6])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 6])); for (int i = 0; i < shortsC.length; i++) { shortsC[i] = (short) (shortsA[i] + (shortsB[i] >>> 35)); shortsD[i] = (short) (shortsA[i] + shortsB[i]); } assertTrue(Arrays.equals(shortsC, gShorts[7])); assertTrue(Arrays.equals(shortsD, gShorts[MAX_TESTS + 7])); } static void test_chars() { for (int i = 0; i < charsC.length; i++) { charsC[i] = (char) (charsA[i] + (charsB[i] >>> 4)); charsC[i] = (char) (charsC[i] + charsA[i] + charsB[i]); } assertTrue(Arrays.equals(charsC, gChars[0])); for (int i = 0; i < charsC.length; i++) { charsC[i] = (char) (charsA[i] + (charsB[i] >>> 16)); charsC[i] = (char) (charsC[i] + charsA[i] + charsB[i]); } assertTrue(Arrays.equals(charsC, gChars[1])); for (int i = 0; i < charsC.length; i++) { charsC[i] = (char) (charsA[i] + (charsB[i] >>> 19)); charsC[i] = (char) (charsC[i] + charsA[i] + charsB[i]); } assertTrue(Arrays.equals(charsC, gChars[2])); for (int i = 0; i < charsC.length; i++) { charsC[i] = (char) (charsA[i] + (charsB[i] >>> 35)); charsC[i] = (char) (charsC[i] + charsA[i] + charsB[i]); } assertTrue(Arrays.equals(charsC, gChars[3])); } static void test_ints() { for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >> 19)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[0])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >> 32)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[1])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >> 49)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[2])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >> 67)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[3])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >>> 19)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[4])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >>> 32)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[5])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >>> 49)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[6])); for (int i = 0; i < intsC.length; i++) { intsC[i] = (intsA[i] + (intsB[i] >>> 67)); intsC[i] = (intsC[i] + intsA[i] + intsB[i]); } assertTrue(Arrays.equals(intsC, gInts[7])); } static void test_longs() { for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >> 37)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[0])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >> 64)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[1])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >> 93)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[2])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >> 137)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[3])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >>> 37)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[4])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >>> 64)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[5])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >>> 93)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[6])); for (int i = 0; i < longsC.length; i++) { longsC[i] = (longsA[i] + (longsB[i] >>> 137)); longsC[i] = (longsC[i] + longsA[i] + longsB[i]); } assertTrue(Arrays.equals(longsC, gLongs[7])); } static void test_init(int count) { int countI = count == SMALL_LEN ? SMALL_INTS_LEN : count; int countB = count == SMALL_LEN ? SMALL_BYTES_LEN : count; bytesA = new byte[countB]; shortsA = new short[count]; charsA = new char[count]; intsA = new int[countI]; longsA = new long[count]; bytesB = new byte[countB]; shortsB = new short[count]; charsB = new char[count]; intsB = new int[countI]; longsB = new long[count]; bytesC = new byte[countB]; shortsC = new short[count]; charsC = new char[count]; intsC = new int[countI]; longsC = new long[count]; bytesD = new byte[countB]; shortsD = new short[count]; gBytes = new byte[MAX_TESTS * 2][countB]; gShorts = new short[MAX_TESTS * 2][count]; gChars = new char[MAX_TESTS][count]; gInts = new int[MAX_TESTS][countI]; gLongs = new long[MAX_TESTS][count]; for (int i = 0; i < countB; i++) { bytesA[i] = (byte) r.nextInt(); bytesB[i] = (byte) r.nextInt(); gBytes[0][i] = (byte) (bytesA[i] + (bytesB[i] >> 1)); gBytes[MAX_TESTS][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[1][i] = (byte) (bytesA[i] + (bytesB[i] >> 8)); gBytes[MAX_TESTS + 1][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[2][i] = (byte) (bytesA[i] + (bytesB[i] >> 13)); gBytes[MAX_TESTS + 2][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[3][i] = (byte) (bytesA[i] + (bytesB[i] >> 19)); gBytes[MAX_TESTS + 3][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[4][i] = (byte) (bytesA[i] + (bytesB[i] >>> 1)); gBytes[MAX_TESTS + 4][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[5][i] = (byte) (bytesA[i] + (bytesB[i] >>> 8)); gBytes[MAX_TESTS + 5][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[6][i] = (byte) (bytesA[i] + (bytesB[i] >>> 13)); gBytes[MAX_TESTS + 6][i] = (byte) (bytesA[i] + bytesB[i]); gBytes[7][i] = (byte) (bytesA[i] + (bytesB[i] >>> 19)); gBytes[MAX_TESTS + 7][i] = (byte) (bytesA[i] + bytesB[i]); } for (int i = 0; i < count; i++) { shortsA[i] = (short) r.nextInt(); charsA[i] = (char) r.nextInt(); longsA[i] = r.nextLong(); shortsB[i] = (short) r.nextInt(); charsB[i] = (char) r.nextInt(); longsB[i] = r.nextLong(); } for (int i = 0; i < count; i++) { gShorts[0][i] = (short) (shortsA[i] + (shortsB[i] >> 5)); gShorts[MAX_TESTS][i] = (short) (shortsA[i] + shortsB[i]); gShorts[1][i] = (short) (shortsA[i] + (shortsB[i] >> 16)); gShorts[MAX_TESTS + 1][i] = (short) (shortsA[i] + shortsB[i]); gShorts[2][i] = (short) (shortsA[i] + (shortsB[i] >> 23)); gShorts[MAX_TESTS + 2][i] = (short) (shortsA[i] + shortsB[i]); gShorts[3][i] = (short) (shortsA[i] + (shortsB[i] >> 35)); gShorts[MAX_TESTS + 3][i] = (short) (shortsA[i] + shortsB[i]); gShorts[4][i] = (short) (shortsA[i] + (shortsB[i] >>> 7)); gShorts[MAX_TESTS + 4][i] = (short) (shortsA[i] + shortsB[i]); gShorts[5][i] = (short) (shortsA[i] + (shortsB[i] >>> 16)); gShorts[MAX_TESTS + 5][i] = (short) (shortsA[i] + shortsB[i]); gShorts[6][i] = (short) (shortsA[i] + (shortsB[i] >>> 23)); gShorts[MAX_TESTS + 6][i] = (short) (shortsA[i] + shortsB[i]); gShorts[7][i] = (short) (shortsA[i] + (shortsB[i] >>> 35)); gShorts[MAX_TESTS + 7][i] = (short) (shortsA[i] + shortsB[i]); gChars[0][i] = (char) (charsA[i] + (charsB[i] >>> 4)); gChars[0][i] = (char) (gChars[0][i] + charsA[i] + charsB[i]); gChars[1][i] = (char) (charsA[i] + (charsB[i] >>> 16)); gChars[1][i] = (char) (gChars[1][i] + charsA[i] + charsB[i]); gChars[2][i] = (char) (charsA[i] + (charsB[i] >>> 19)); gChars[2][i] = (char) (gChars[2][i] + charsA[i] + charsB[i]); gChars[3][i] = (char) (charsA[i] + (charsB[i] >>> 35)); gChars[3][i] = (char) (gChars[3][i] + charsA[i] + charsB[i]); gLongs[0][i] = longsA[i] + (longsB[i] >> 37); gLongs[0][i] = gLongs[0][i] + longsA[i] + longsB[i]; gLongs[1][i] = longsA[i] + (longsB[i] >> 64); gLongs[1][i] = gLongs[1][i] + longsA[i] + longsB[i]; gLongs[2][i] = longsA[i] + (longsB[i] >> 93); gLongs[2][i] = gLongs[2][i] + longsA[i] + longsB[i]; gLongs[3][i] = longsA[i] + (longsB[i] >> 137); gLongs[3][i] = gLongs[3][i] + longsA[i] + longsB[i]; gLongs[4][i] = longsA[i] + (longsB[i] >>> 37); gLongs[4][i] = gLongs[4][i] + longsA[i] + longsB[i]; gLongs[5][i] = longsA[i] + (longsB[i] >>> 64); gLongs[5][i] = gLongs[5][i] + longsA[i] + longsB[i]; gLongs[6][i] = longsA[i] + (longsB[i] >>> 93); gLongs[6][i] = gLongs[6][i] + longsA[i] + longsB[i]; gLongs[7][i] = longsA[i] + (longsB[i] >>> 137); gLongs[7][i] = gLongs[7][i] + longsA[i] + longsB[i]; } for (int i = 0; i < intsA.length; i++) { intsA[i] = r.nextInt(); intsB[i] = r.nextInt(); gInts[0][i] = intsA[i] + (intsB[i] >> 19); gInts[0][i] = gInts[0][i] + intsA[i] + intsB[i]; gInts[1][i] = intsA[i] + (intsB[i] >> 32); gInts[1][i] = gInts[1][i] + intsA[i] + intsB[i]; gInts[2][i] = intsA[i] + (intsB[i] >> 49); gInts[2][i] = gInts[2][i] + intsA[i] + intsB[i]; gInts[3][i] = intsA[i] + (intsB[i] >> 67); gInts[3][i] = gInts[3][i] + intsA[i] + intsB[i]; gInts[4][i] = intsA[i] + (intsB[i] >>> 19); gInts[4][i] = gInts[4][i] + intsA[i] + intsB[i]; gInts[5][i] = intsA[i] + (intsB[i] >>> 32); gInts[5][i] = gInts[5][i] + intsA[i] + intsB[i]; gInts[6][i] = intsA[i] + (intsB[i] >>> 49); gInts[6][i] = gInts[6][i] + intsA[i] + intsB[i]; gInts[7][i] = intsA[i] + (intsB[i] >>> 67); gInts[7][i] = gInts[7][i] + intsA[i] + intsB[i]; } } static void assertTrue(boolean okay) { if (!okay) { throw new RuntimeException("Test Failed"); } } }