diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 3ee03b4b390..922e412356d 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -1417,6 +1417,7 @@ enum VectorMask { INSN(vmfeq_vv, 0b1010111, 0b001, 0b011000); // Vector Floating-Point Sign-Injection Instructions + INSN(vfsgnj_vv, 0b1010111, 0b001, 0b001000); INSN(vfsgnjx_vv, 0b1010111, 0b001, 0b001010); INSN(vfsgnjn_vv, 0b1010111, 0b001, 0b001001); diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 7a88c416f2a..ab84ef7f8a1 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1677,6 +1677,19 @@ void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister one, bool is_ bind(done); } +void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen) { + vsetvli_helper(bt, vlen); + + // check if input is -0, +0, signaling NaN or quiet NaN + vfclass_v(v0, dst); + mv(t0, fclass_mask::zero | fclass_mask::nan); + vand_vx(v0, v0, t0); + vmseq_vi(v0, v0, 0); + + // use floating-point 1.0 with a sign of input + vfsgnj_vv(dst, one, dst, v0_t); +} + void C2_MacroAssembler::compress_bits_v(Register dst, Register src, Register mask, bool is_long) { Assembler::SEW sew = is_long ? Assembler::e64 : Assembler::e32; // intrinsic is enabled when MaxVectorSize >= 16 diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index f36615809c0..b9a7749631a 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -163,6 +163,8 @@ void signum_fp(FloatRegister dst, FloatRegister one, bool is_double); + void signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen); + // intrinsic methods implemented by rvv instructions // compress bits, i.e. j.l.Integer/Long::compress. diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index f4d406002d0..c163325fc81 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -3660,6 +3660,23 @@ instruct vexpand(vReg dst, vReg src, vRegMask_V0 v0, vReg tmp) %{ ins_pipe(pipe_slow); %} +// ------------------------------ Vector signum -------------------------------- + +// Vector Math.signum + +instruct vsignum_reg(vReg dst, vReg zero, vReg one, vRegMask_V0 v0) %{ + match(Set dst (SignumVF dst (Binary zero one))); + match(Set dst (SignumVD dst (Binary zero one))); + effect(TEMP_DEF dst, TEMP v0); + format %{ "vsignum $dst, $dst\t" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ signum_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($one$$reg), + bt, Matcher::vector_length(this)); + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector Load Gather --------------------------- instruct gather_load(vReg dst, indirect mem, vReg idx) %{ diff --git a/test/hotspot/jtreg/compiler/vectorization/TestSignumVector.java b/test/hotspot/jtreg/compiler/vectorization/TestSignumVector.java index db85a61cc75..66943d68a67 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestSignumVector.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestSignumVector.java @@ -24,9 +24,11 @@ /** * @test * @bug 8282711 8290249 - * @summary Accelerate Math.signum function for AVX, AVX512 and aarch64 (Neon and SVE) + * @summary Accelerate Math.signum function for AVX, AVX512, aarch64 (Neon and SVE) + * and riscv64 (vector) * @requires vm.compiler2.enabled - * @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*avx.*") | os.arch == "aarch64" + * @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*avx.*") | os.arch == "aarch64" | + * (os.arch == "riscv64" & vm.cpu.features ~= ".*v,.*") * @library /test/lib / * @run driver compiler.vectorization.TestSignumVector */