133419177d
Reviewed-by: fyang, rehn, luhenry
505 lines
17 KiB
Java
505 lines
17 KiB
Java
/*
|
|
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. 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 8283894
|
|
* @key randomness
|
|
* @summary To test various transforms added for bit COMPRESS_BITS and EXPAND_BITS operations
|
|
* @requires vm.compiler2.enabled
|
|
* @requires (((os.arch=="x86" | os.arch=="amd64" | os.arch=="x86_64") &
|
|
* (vm.cpu.features ~= ".*bmi2.*" & vm.cpu.features ~= ".*bmi1.*" &
|
|
* vm.cpu.features ~= ".*sse2.*")) |
|
|
* (os.arch=="aarch64" & vm.cpu.features ~= ".*svebitperm.*"))
|
|
* @library /test/lib /
|
|
* @run driver compiler.intrinsics.TestBitShuffleOpers
|
|
*/
|
|
package compiler.intrinsics;
|
|
|
|
import java.util.concurrent.Callable;
|
|
import compiler.lib.ir_framework.*;
|
|
import jdk.test.lib.Utils;
|
|
import java.util.Random;
|
|
|
|
public class TestBitShuffleOpers {
|
|
int [] ri;
|
|
int [] ai;
|
|
int [] bi;
|
|
|
|
long [] rl;
|
|
long [] al;
|
|
long [] bl;
|
|
|
|
//===================== Compress Bits Transforms ================
|
|
@Test
|
|
@IR(counts = {IRNode.RSHIFT_I, " > 0 ", IRNode.AND_I, " > 0"})
|
|
public void test1(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.compress(ai[i], 1 << bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test1"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test1() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test1(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.URSHIFT_I, " > 0 "})
|
|
public void test2(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.compress(ai[i], -1 << bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test2"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test2() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test2(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 ", IRNode.AND_I , " > 0 "})
|
|
public void test3(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.compress(Integer.expand(ai[i], bi[i]), bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test3"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test3() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test3(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.RSHIFT_L, " > 0 ", IRNode.AND_L, " > 0"})
|
|
public void test4(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.compress(al[i], 1L << bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test4"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test4() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test4(rl, al, bl);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.URSHIFT_L, " > 0 "})
|
|
public void test5(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.compress(al[i], -1L << bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test5"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test5() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test5(rl, al, bl);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 ", IRNode.AND_L , " > 0 "})
|
|
public void test6(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.compress(Long.expand(al[i], bl[i]), bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test6"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test6() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test6(rl, al, bl);
|
|
}
|
|
}
|
|
//===================== Expand Bits Transforms ================
|
|
@Test
|
|
@IR(counts = {IRNode.LSHIFT_I, " > 0 ", IRNode.AND_I, " > 0"})
|
|
public void test7(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.expand(ai[i], 1 << bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test7"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test7() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test7(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.LSHIFT_I, " > 0 "})
|
|
public void test8(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.expand(ai[i], -1 << bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test8"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test8() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test8(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.AND_I , " > 0 "})
|
|
public void test9(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.expand(Integer.compress(ai[i], bi[i]), bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test9"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test9() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test9(ri, ai, bi);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.LSHIFT_L, " > 0 ", IRNode.AND_L, " > 0"})
|
|
public void test10(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.expand(al[i], 1L << bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test10"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test10() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test10(rl, al, bl);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.LSHIFT_L, " > 0 "})
|
|
public void test11(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.expand(al[i], -1L << bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test11"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test11() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test11(rl, al, bl);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.AND_L , " > 0 "})
|
|
public void test12(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.expand(Long.compress(al[i], bl[i]), bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test12"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test12() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test12(rl, al, bl);
|
|
}
|
|
}
|
|
|
|
// ================ Compress/ExpandBits Vanilla ================= //
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 "})
|
|
public void test13(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.compress(ai[i], bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test13"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test13() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test13(ri, ai, bi);
|
|
}
|
|
verifyCompressInts(ri, ai, bi);
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.COMPRESS_BITS, " > 0 "})
|
|
public void test14(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.compress(al[i], bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test14"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test14() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test14(rl, al, bl);
|
|
}
|
|
verifyCompressLongs(rl, al, bl);
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.EXPAND_BITS, " > 0 "})
|
|
public void test15(int[] ri, int[] ai, int[] bi) {
|
|
for (int i = 0; i < ri.length; i++) {
|
|
ri[i] = Integer.expand(ai[i], bi[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test15"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test15() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test15(ri, ai, bi);
|
|
}
|
|
verifyExpandInts(ri, ai, bi);
|
|
}
|
|
|
|
@Test
|
|
@IR(counts = {IRNode.EXPAND_BITS, " > 0 "})
|
|
public void test16(long[] rl, long[] al, long[] bl) {
|
|
for (int i = 0; i < rl.length; i++) {
|
|
rl[i] = Long.expand(al[i], bl[i]);
|
|
}
|
|
}
|
|
|
|
@Run(test = {"test16"}, mode = RunMode.STANDALONE)
|
|
public void kernel_test16() {
|
|
for (int i = 0; i < 5000; i++) {
|
|
test16(rl, al, bl);
|
|
}
|
|
verifyExpandLongs(rl, al, bl);
|
|
}
|
|
|
|
@Test
|
|
public void test17() {
|
|
int resI = 0;
|
|
long resL = 0L;
|
|
for (int i = 0; i < 5000; i++) {
|
|
resI = Integer.expand(-1, -1);
|
|
verifyExpandInt(resI, -1, -1);
|
|
resI = Integer.compress(-1, -1);
|
|
verifyCompressInt(resI, -1, -1);
|
|
|
|
resI = Integer.expand(ai[i&(SIZE-1)], -1);
|
|
verifyExpandInt(resI, ai[i&(SIZE-1)], -1);
|
|
resI = Integer.expand(ai[i&(SIZE-1)], -2);
|
|
verifyExpandInt(resI, ai[i&(SIZE-1)], -2);
|
|
resI = Integer.expand(ai[i&(SIZE-1)], 5);
|
|
verifyExpandInt(resI, ai[i&(SIZE-1)], 5);
|
|
resI = Integer.compress(ai[i&(SIZE-1)], -1);
|
|
verifyCompressInt(resI, ai[i&(SIZE-1)], -1);
|
|
resI = Integer.compress(ai[i&(SIZE-1)], -2);
|
|
verifyCompressInt(resI, ai[i&(SIZE-1)], -2);
|
|
resI = Integer.compress(ai[i&(SIZE-1)], 5);
|
|
verifyCompressInt(resI, ai[i&(SIZE-1)], 5);
|
|
|
|
resI = Integer.expand(ai[i&(SIZE-1)], bi[i&(SIZE-1)] & ~(0x10000000));
|
|
verifyExpandInt(resI, ai[i&(SIZE-1)], bi[i&(SIZE-1)] & ~(0x10000000));
|
|
resI = Integer.expand(ai[i&(SIZE-1)], bi[i&(SIZE-1)] | (0x10000000));
|
|
verifyExpandInt(resI, ai[i&(SIZE-1)], bi[i&(SIZE-1)] | (0x10000000));
|
|
resI = Integer.compress(ai[i&(SIZE-1)], bi[i&(SIZE-1)] & ~(0x10000000));
|
|
verifyCompressInt(resI, ai[i&(SIZE-1)], bi[i&(SIZE-1)] & ~(0x10000000));
|
|
resI = Integer.compress(ai[i&(SIZE-1)], bi[i&(SIZE-1)] | (0x10000000));
|
|
verifyCompressInt(resI, ai[i&(SIZE-1)], bi[i&(SIZE-1)] | (0x10000000));
|
|
|
|
resI = Integer.compress(0x12123434, 0xFF00FF00);
|
|
verifyCompressInt(resI, 0x12123434, 0xFF00FF00);
|
|
resI = Integer.expand(0x12123434, 0xFF00FF00);
|
|
verifyExpandInt(resI, 0x12123434, 0xFF00FF00);
|
|
|
|
resL = Long.expand(-1L, -1L);
|
|
verifyExpandLong(resL, -1L, -1L);
|
|
resL = Long.compress(-1L, -1L);
|
|
verifyCompressLong(resL, -1L, -1L);
|
|
|
|
resL = Long.compress(0x1212343412123434L, 0xFF00FF00FF00FF00L);
|
|
verifyCompressLong(resL, 0x1212343412123434L, 0xFF00FF00FF00FF00L);
|
|
resL = Long.expand(0x1212343412123434L, 0xFF00FF00FF00FF00L);
|
|
verifyExpandLong(resL, 0x1212343412123434L, 0xFF00FF00FF00FF00L);
|
|
|
|
resL = Long.expand(al[i&(SIZE-1)], -1);
|
|
verifyExpandLong(resL, al[i&(SIZE-1)], -1);
|
|
resL = Long.expand(al[i&(SIZE-1)], -2);
|
|
verifyExpandLong(resL, al[i&(SIZE-1)], -2);
|
|
resL = Long.expand(al[i&(SIZE-1)], 5);
|
|
verifyExpandLong(resL, al[i&(SIZE-1)], 5);
|
|
resL = Long.compress(al[i&(SIZE-1)], -1);
|
|
verifyCompressLong(resL, al[i&(SIZE-1)], -1);
|
|
resL = Long.compress(al[i&(SIZE-1)], -2);
|
|
verifyCompressLong(resL, al[i&(SIZE-1)], -2);
|
|
resL = Long.compress(al[i&(SIZE-1)], 5);
|
|
verifyCompressLong(resL, al[i&(SIZE-1)], 5);
|
|
|
|
resL = Long.expand(al[i&(SIZE-1)], bl[i&(SIZE-1)] & ~(0x10000000));
|
|
verifyExpandLong(resL, al[i&(SIZE-1)], bl[i&(SIZE-1)] & ~(0x10000000));
|
|
resL = Long.expand(al[i&(SIZE-1)], bl[i&(SIZE-1)] | (0x10000000));
|
|
verifyExpandLong(resL, al[i&(SIZE-1)], bl[i&(SIZE-1)] | (0x10000000));
|
|
resL = Long.compress(al[i&(SIZE-1)], bl[i&(SIZE-1)] & ~(0x10000000));
|
|
verifyCompressLong(resL, al[i&(SIZE-1)], bl[i&(SIZE-1)] & ~(0x10000000));
|
|
resL = Long.compress(al[i&(SIZE-1)], bl[i&(SIZE-1)] | (0x10000000));
|
|
verifyCompressLong(resL, al[i&(SIZE-1)], bl[i&(SIZE-1)] | (0x10000000));
|
|
}
|
|
}
|
|
|
|
private static final Random R = Utils.getRandomInstance();
|
|
|
|
static int[] fillIntRandom(Callable<int[]> factory) {
|
|
try {
|
|
int[] arr = factory.call();
|
|
for (int i = 0; i < arr.length; i++) {
|
|
arr[i] = R.nextInt();
|
|
}
|
|
return arr;
|
|
} catch (Exception e) {
|
|
throw new InternalError(e);
|
|
}
|
|
}
|
|
static long[] fillLongRandom(Callable<long[]> factory) {
|
|
try {
|
|
long[] arr = factory.call();
|
|
for (int i = 0; i < arr.length; i++) {
|
|
arr[i] = R.nextLong();
|
|
}
|
|
return arr;
|
|
} catch (Exception e) {
|
|
throw new InternalError(e);
|
|
}
|
|
}
|
|
|
|
static void verifyExpandInt(int actual, int src, int mask) {
|
|
int exp = 0;
|
|
for(int j = 0, k = 0; j < Integer.SIZE; j++) {
|
|
if ((mask & 0x1) == 1) {
|
|
exp |= (src & 0x1) << j;
|
|
src >>= 1;
|
|
}
|
|
mask >>= 1;
|
|
}
|
|
if (actual != exp) {
|
|
throw new Error("expand_int: src = " + src + " mask = " + mask +
|
|
" acutal = " + actual + " expected = " + exp);
|
|
}
|
|
}
|
|
|
|
static void verifyExpandInts(int [] actual_res, int [] inp_arr, int [] mask_arr) {
|
|
assert inp_arr.length == mask_arr.length && inp_arr.length == actual_res.length;
|
|
for(int i = 0; i < actual_res.length; i++) {
|
|
verifyExpandInt(actual_res[i], inp_arr[i], mask_arr[i]);
|
|
}
|
|
}
|
|
|
|
static void verifyExpandLong(long actual, long src, long mask) {
|
|
long exp = 0;
|
|
for(int j = 0, k = 0; j < Long.SIZE; j++) {
|
|
if ((mask & 0x1) == 1) {
|
|
exp |= (src & 0x1) << j;
|
|
src >>= 1;
|
|
}
|
|
mask >>= 1;
|
|
}
|
|
if (actual != exp) {
|
|
throw new Error("expand_long: src = " + src + " mask = " + mask +
|
|
" acutal = " + actual + " expected = " + exp);
|
|
}
|
|
}
|
|
|
|
static void verifyExpandLongs(long [] actual_res, long [] inp_arr, long [] mask_arr) {
|
|
assert inp_arr.length == mask_arr.length && inp_arr.length == actual_res.length;
|
|
for(int i = 0; i < actual_res.length; i++) {
|
|
verifyExpandLong(actual_res[i], inp_arr[i], mask_arr[i]);
|
|
}
|
|
}
|
|
|
|
static void verifyCompressInt(int actual, int src, int mask) {
|
|
int exp = 0;
|
|
for(int j = 0, k = 0; j < Integer.SIZE; j++) {
|
|
if ((mask & 0x1) == 1) {
|
|
exp |= (src & 0x1) << k++;
|
|
}
|
|
mask >>= 1;
|
|
src >>= 1;
|
|
}
|
|
if (actual != exp) {
|
|
throw new Error("compress_int: src = " + src + " mask = " + mask +
|
|
" acutal = " + actual + " expected = " + exp);
|
|
}
|
|
}
|
|
|
|
static void verifyCompressInts(int [] actual_res, int [] inp_arr, int [] mask_arr) {
|
|
assert inp_arr.length == mask_arr.length && inp_arr.length == actual_res.length;
|
|
for(int i = 0; i < actual_res.length; i++) {
|
|
verifyCompressInt(actual_res[i], inp_arr[i], mask_arr[i]);
|
|
}
|
|
}
|
|
|
|
static void verifyCompressLong(long actual, long src, long mask) {
|
|
long exp = 0;
|
|
for(int j = 0, k = 0; j < Long.SIZE; j++) {
|
|
if ((mask & 0x1) == 1) {
|
|
exp |= (src & 0x1) << k++;
|
|
}
|
|
mask >>= 1;
|
|
src >>= 1;
|
|
}
|
|
if (actual != exp) {
|
|
throw new Error("compress_long: src = " + src + " mask = " + mask +
|
|
" acutal = " + actual + " expected = " + exp);
|
|
}
|
|
}
|
|
|
|
static void verifyCompressLongs(long [] actual_res, long [] inp_arr, long [] mask_arr) {
|
|
assert inp_arr.length == mask_arr.length && inp_arr.length == actual_res.length;
|
|
for(int i = 0; i < actual_res.length; i++) {
|
|
verifyCompressLong(actual_res[i], inp_arr[i], mask_arr[i]);
|
|
}
|
|
}
|
|
|
|
// ===================================================== //
|
|
|
|
static final int SIZE = 512;
|
|
|
|
|
|
public TestBitShuffleOpers() {
|
|
ri = new int[SIZE];
|
|
ai = fillIntRandom(()-> new int[SIZE]);
|
|
bi = fillIntRandom(()-> new int[SIZE]);
|
|
|
|
rl = new long[SIZE];
|
|
al = fillLongRandom(() -> new long[SIZE]);
|
|
bl = fillLongRandom(() -> new long[SIZE]);
|
|
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
TestFramework.runWithFlags("-XX:-TieredCompilation",
|
|
"-XX:CompileThresholdScaling=0.3");
|
|
}
|
|
}
|