diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index cd9d2107b79..1e99b2ece29 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -80,8 +80,12 @@ source %{ case Op_PopCountVI: case Op_ReverseBytesV: case Op_ReverseV: + return UseZvbb; case Op_RotateLeftV: case Op_RotateRightV: + if (bt != T_INT && bt != T_LONG) { + return false; + } return UseZvbb; case Op_LoadVectorGather: case Op_LoadVectorGatherMasked: @@ -3413,27 +3417,6 @@ instruct vshiftcnt(vReg dst, iRegIorL2I cnt) %{ %} // --------------------------------- Vector Rotation ---------------------------------- -// -// Following rotate instruct's are shared by vectorization (in SLP, superword.cpp) and Vector API. -// -// Rotate behaviour in vectorization is defined by java API, which includes: -// 1. Integer.rorateRight, Integer.rorateLeft. -// `rotation by any multiple of 32 is a no-op, so all but the last five bits of the rotation distance can be ignored`. -// 2. Long.rorateRight, Long.rorateLeft. -// `rotation by any multiple of 64 is a no-op, so all but the last six bits of the rotation distance can be ignored`. -// -// Rotate behaviour in Vector API is defined as below, e.g. -// 1. For Byte ROR, `a ROR b` is: (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7)))) -// 2. For Short ROR, `a ROR b` is: (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15)))) -// 3. For Integer ROR, `a ROR b` is: Integer.rotateRight(a, ((int)b)) -// 4. For Long ROR, `a ROR b` is: Long.rotateRight(a, ((int)b)) -// -// Basically, the behaviour between vectorization and Vector API is the same for Long and Integer, except that Vector API -// also supports Byte and Short rotation. But we can still share the intrinsics between vectorization and Vector API. -// -// NOTE: As vror.vi encodes 6-bits immediate rotate amount, which is different from other vector-immediate instructions, -// implementation of vector rotation for long and other types can be unified. - // Rotate right instruct vrotate_right(vReg dst, vReg src, vReg shift) %{ diff --git a/test/hotspot/jtreg/compiler/vectorization/TestRotateByteAndShortVector.java b/test/hotspot/jtreg/compiler/vectorization/TestRotateByteAndShortVector.java index 08e69485d56..e130fc0ba6c 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestRotateByteAndShortVector.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestRotateByteAndShortVector.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2022, Loongson Technology Co. Ltd. All rights reserved. + * Copyright (c) 2022, 2025 Loongson Technology Co. Ltd. All rights reserved. + * Copyright (c) 2025, Rivos Inc. 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 @@ -23,15 +24,16 @@ /** * @test - * @bug 8286847 + * @bug 8286847 8353600 * @key randomness * @summary Test vectorization of rotate byte and short - * @library /test/lib - * @run main/othervm -XX:-TieredCompilation -XX:CompileCommand=compileonly,TestRotateByteAndShortVector::testRotate* -Xbatch TestRotateByteAndShortVector + * @library /test/lib / + * @run main/othervm TestRotateByteAndShortVector */ import java.util.Random; import jdk.test.lib.Utils; +import compiler.lib.ir_framework.*; public class TestRotateByteAndShortVector { private static final Random random = Utils.getRandomInstance(); @@ -49,27 +51,7 @@ public class TestRotateByteAndShortVector { private static short resShort = 0; public static void main(String[] args) { - System.out.println("warmup"); - warmup(); - - System.out.println("Testing..."); - runRotateLeftByteTest(); - runRotateRightByteTest(); - runRotateLeftShortTest(); - runRotateRightShortTest(); - - System.out.println("PASSED"); - } - - static void warmup() { - random.nextBytes(arrByte); - randomShorts(); - for (int i = 0; i < ITERS; i++) { - testRotateLeftByte(rolByte, arrByte, i); - testRotateRightByte(rorByte, arrByte, i); - testRotateLeftShort(rolShort, arrShort, i); - testRotateRightShort(rorShort, arrShort, i); - } + TestFramework.run(); } static void randomShorts() { @@ -78,6 +60,7 @@ public class TestRotateByteAndShortVector { } } + @Run(test = { "testRotateLeftByte" }) static void runRotateLeftByteTest() { for (int shift = 0; shift < 64; shift++) { random.nextBytes(arrByte); @@ -91,6 +74,7 @@ public class TestRotateByteAndShortVector { } } + @Run(test = { "testRotateRightByte" }) static void runRotateRightByteTest() { for (int shift = 0; shift < 64; shift++) { random.nextBytes(arrByte); @@ -104,6 +88,7 @@ public class TestRotateByteAndShortVector { } } + @Run(test = { "testRotateLeftShort" }) static void runRotateLeftShortTest() { for (int shift = 0; shift < 64; shift++) { randomShorts(); @@ -117,6 +102,7 @@ public class TestRotateByteAndShortVector { } } + @Run(test = { "testRotateRightShort" }) static void runRotateRightShortTest() { for (int shift = 0; shift < 64; shift++) { randomShorts(); @@ -130,24 +116,39 @@ public class TestRotateByteAndShortVector { } } + // NOTE: currently, there is no platform supporting RotateLeftV/RotateRightV intrinsic. + // If there is some implementation, it could probably in a wrong way which is different + // from what java language spec expects. + @Test + @IR(failOn = { IRNode.ROTATE_LEFT_V }) + @IR(failOn = { IRNode.ROTATE_RIGHT_V }) static void testRotateLeftByte(byte[] test, byte[] arr, int shift) { for (int i = 0; i < ARRLEN; i++) { test[i] = (byte) ((arr[i] << shift) | (arr[i] >>> -shift)); } } + @Test + @IR(failOn = { IRNode.ROTATE_LEFT_V }) + @IR(failOn = { IRNode.ROTATE_RIGHT_V }) static void testRotateRightByte(byte[] test, byte[] arr, int shift) { for (int i = 0; i < ARRLEN; i++) { test[i] = (byte) ((arr[i] >>> shift) | (arr[i] << -shift)); } } + @Test + @IR(failOn = { IRNode.ROTATE_LEFT_V }) + @IR(failOn = { IRNode.ROTATE_RIGHT_V }) static void testRotateLeftShort(short[] test, short[] arr, int shift) { for (int i = 0; i < ARRLEN; i++) { test[i] = (short) ((arr[i] << shift) | (arr[i] >>> -shift)); } } + @Test + @IR(failOn = { IRNode.ROTATE_LEFT_V }) + @IR(failOn = { IRNode.ROTATE_RIGHT_V }) static void testRotateRightShort(short[] test, short[] arr, int shift) { for (int i = 0; i < ARRLEN; i++) { test[i] = (short) ((arr[i] >>> shift) | (arr[i] << -shift));