jdk-24/test/hotspot/jtreg/compiler/intrinsics/TestBitShuffleOpers.java
2024-06-17 11:35:41 +00:00

506 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.*") |
* (os.arch=="riscv64" & vm.cpu.features ~= ".*rvv.*"))
* @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");
}
}