diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 94ab400e40a..d904675a117 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -4011,18 +4011,6 @@ void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, Compa emit_int8(vcc); } -void Assembler::evpcmpuw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len) { - assert(VM_Version::supports_avx512vlbw(), ""); - InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); - attributes.reset_is_clear_context(); - attributes.set_embedded_opmask_register_specifier(mask); - attributes.set_is_evex_instruction(); - int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int8(0x3E); - emit_int8((unsigned char)(0xC0 | encode)); - emit_int8(vcc); -} - void Assembler::evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len) { assert(VM_Version::supports_avx512vlbw(), ""); InstructionMark im(this); @@ -9256,7 +9244,7 @@ void Assembler::vpcmpgtq(XMMRegister dst, XMMRegister nds, XMMRegister src, int } void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); // Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib @@ -9265,11 +9253,12 @@ void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegi attributes.set_embedded_opmask_register_specifier(mask); attributes.reset_is_clear_context(); int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int24(0x1F, (0xC0 | encode), comparison); + int opcode = is_signed ? 0x1F : 0x1E; + emit_int24(opcode, (0xC0 | encode), comparison); } void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); // Encoding: EVEX.NDS.XXX.66.0F3A.W0 1F /r ib @@ -9281,13 +9270,14 @@ void Assembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, Address attributes.reset_is_clear_context(); int dst_enc = kdst->encoding(); vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int8((unsigned char)0x1F); + int opcode = is_signed ? 0x1F : 0x1E; + emit_int8((unsigned char)opcode); emit_operand(as_Register(dst_enc), src); emit_int8((unsigned char)comparison); } void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); // Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib @@ -9296,11 +9286,12 @@ void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegi attributes.set_embedded_opmask_register_specifier(mask); attributes.reset_is_clear_context(); int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int24(0x1F, (0xC0 | encode), comparison); + int opcode = is_signed ? 0x1F : 0x1E; + emit_int24(opcode, (0xC0 | encode), comparison); } void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); // Encoding: EVEX.NDS.XXX.66.0F3A.W1 1F /r ib @@ -9312,13 +9303,14 @@ void Assembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, Address attributes.reset_is_clear_context(); int dst_enc = kdst->encoding(); vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int8((unsigned char)0x1F); + int opcode = is_signed ? 0x1F : 0x1E; + emit_int8((unsigned char)opcode); emit_operand(as_Register(dst_enc), src); emit_int8((unsigned char)comparison); } void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(VM_Version::supports_avx512bw(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); @@ -9328,11 +9320,12 @@ void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegi attributes.set_embedded_opmask_register_specifier(mask); attributes.reset_is_clear_context(); int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int24(0x3F, (0xC0 | encode), comparison); + int opcode = is_signed ? 0x3F : 0x3E; + emit_int24(opcode, (0xC0 | encode), comparison); } void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(VM_Version::supports_avx512bw(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); @@ -9345,13 +9338,14 @@ void Assembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, Address attributes.reset_is_clear_context(); int dst_enc = kdst->encoding(); vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int8((unsigned char)0x3F); + int opcode = is_signed ? 0x3F : 0x3E; + emit_int8((unsigned char)opcode); emit_operand(as_Register(dst_enc), src); emit_int8((unsigned char)comparison); } void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(VM_Version::supports_avx512bw(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); @@ -9361,11 +9355,12 @@ void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegi attributes.set_embedded_opmask_register_specifier(mask); attributes.reset_is_clear_context(); int encode = vex_prefix_and_encode(kdst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int24(0x3F, (0xC0 | encode), comparison); + int opcode = is_signed ? 0x3F : 0x3E; + emit_int24(opcode, (0xC0 | encode), comparison); } void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len) { + int comparison, bool is_signed, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(VM_Version::supports_avx512bw(), ""); assert(comparison >= Assembler::eq && comparison <= Assembler::_true, ""); @@ -9378,7 +9373,8 @@ void Assembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address attributes.reset_is_clear_context(); int dst_enc = kdst->encoding(); vex_prefix(src, nds->encoding(), dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); - emit_int8((unsigned char)0x3F); + int opcode = is_signed ? 0x3F : 0x3E; + emit_int8((unsigned char)opcode); emit_operand(as_Register(dst_enc), src); emit_int8((unsigned char)comparison); } diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index a55c45451a3..0892fb5e4cb 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -1742,7 +1742,6 @@ class Assembler : public AbstractAssembler { void evpcmpgtb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len); void evpcmpuw(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len); - void evpcmpuw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, ComparisonPredicate of, int vector_len); void evpcmpuw(KRegister kdst, XMMRegister nds, Address src, ComparisonPredicate vcc, int vector_len); void pcmpeqw(XMMRegister dst, XMMRegister src); @@ -2452,27 +2451,27 @@ class Assembler : public AbstractAssembler { // Vector integer compares void vpcmpgtd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); void evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); // Vector long compares void evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); void evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); // Vector byte compares void evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); void evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); // Vector short compares void evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); void evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, Address src, - int comparison, int vector_len); + int comparison, bool is_signed, int vector_len); void evpmovb2m(KRegister dst, XMMRegister src, int vector_len); diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 8f56fe189a9..8031dc7be86 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1209,18 +1209,18 @@ void C2_MacroAssembler::get_elem(BasicType typ, XMMRegister dst, XMMRegister src void C2_MacroAssembler::evpcmp(BasicType typ, KRegister kdmask, KRegister ksmask, XMMRegister src1, AddressLiteral adr, int comparison, int vector_len, Register scratch) { switch(typ) { case T_BYTE: - evpcmpb(kdmask, ksmask, src1, adr, comparison, vector_len, scratch); + evpcmpb(kdmask, ksmask, src1, adr, comparison, /*signed*/ true, vector_len, scratch); break; case T_SHORT: - evpcmpw(kdmask, ksmask, src1, adr, comparison, vector_len, scratch); + evpcmpw(kdmask, ksmask, src1, adr, comparison, /*signed*/ true, vector_len, scratch); break; case T_INT: case T_FLOAT: - evpcmpd(kdmask, ksmask, src1, adr, comparison, vector_len, scratch); + evpcmpd(kdmask, ksmask, src1, adr, comparison, /*signed*/ true, vector_len, scratch); break; case T_LONG: case T_DOUBLE: - evpcmpq(kdmask, ksmask, src1, adr, comparison, vector_len, scratch); + evpcmpq(kdmask, ksmask, src1, adr, comparison, /*signed*/ true, vector_len, scratch); break; default: assert(false,"Should not reach here."); @@ -1228,6 +1228,84 @@ void C2_MacroAssembler::evpcmp(BasicType typ, KRegister kdmask, KRegister ksmask } } +void C2_MacroAssembler::vpcmpu(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, + int vlen_in_bytes, XMMRegister vtmp1, XMMRegister vtmp2, Register scratch) { + int vlen_enc = vector_length_encoding(vlen_in_bytes*2); + switch (typ) { + case T_BYTE: + vpmovzxbw(vtmp1, src1, vlen_enc); + vpmovzxbw(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); + vpacksswb(dst, dst, dst, vlen_enc); + break; + case T_SHORT: + vpmovzxwd(vtmp1, src1, vlen_enc); + vpmovzxwd(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); + vpackssdw(dst, dst, dst, vlen_enc); + break; + case T_INT: + vpmovzxdq(vtmp1, src1, vlen_enc); + vpmovzxdq(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); + vpermilps(dst, dst, 8, vlen_enc); + break; + default: + assert(false, "Should not reach here"); + } + if (vlen_in_bytes == 16) { + vpermpd(dst, dst, 0x8, vlen_enc); + } +} + +void C2_MacroAssembler::vpcmpu32(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, + XMMRegister vtmp1, XMMRegister vtmp2, XMMRegister vtmp3, Register scratch) { + int vlen_enc = vector_length_encoding(vlen_in_bytes); + switch (typ) { + case T_BYTE: + vpmovzxbw(vtmp1, src1, vlen_enc); + vpmovzxbw(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); + vextracti128(vtmp1, src1, 1); + vextracti128(vtmp2, src2, 1); + vpmovzxbw(vtmp1, vtmp1, vlen_enc); + vpmovzxbw(vtmp2, vtmp2, vlen_enc); + vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::W, vlen_enc, scratch); + vpacksswb(dst, dst, vtmp3, vlen_enc); + vpermpd(dst, dst, 0xd8, vlen_enc); + break; + case T_SHORT: + vpmovzxwd(vtmp1, src1, vlen_enc); + vpmovzxwd(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); + vextracti128(vtmp1, src1, 1); + vextracti128(vtmp2, src2, 1); + vpmovzxwd(vtmp1, vtmp1, vlen_enc); + vpmovzxwd(vtmp2, vtmp2, vlen_enc); + vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::D, vlen_enc, scratch); + vpackssdw(dst, dst, vtmp3, vlen_enc); + vpermpd(dst, dst, 0xd8, vlen_enc); + break; + case T_INT: + vpmovzxdq(vtmp1, src1, vlen_enc); + vpmovzxdq(vtmp2, src2, vlen_enc); + vpcmpCCW(dst, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); + vpshufd(dst, dst, 8, vlen_enc); + vpermq(dst, dst, 8, vlen_enc); + vextracti128(vtmp1, src1, 1); + vextracti128(vtmp2, src2, 1); + vpmovzxdq(vtmp1, vtmp1, vlen_enc); + vpmovzxdq(vtmp2, vtmp2, vlen_enc); + vpcmpCCW(vtmp3, vtmp1, vtmp2, comparison, Assembler::Q, vlen_enc, scratch); + vpshufd(vtmp3, vtmp3, 8, vlen_enc); + vpermq(vtmp3, vtmp3, 0x80, vlen_enc); + vpblendd(dst, dst, vtmp3, 0xf0, vlen_enc); + break; + default: + assert(false, "Should not reach here"); + } +} + void C2_MacroAssembler::evpblend(BasicType typ, XMMRegister dst, KRegister kmask, XMMRegister src1, XMMRegister src2, bool merge, int vector_len) { switch(typ) { case T_BYTE: diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index eabaf78aa7f..ac07e650952 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -87,6 +87,12 @@ void load_vector_mask(XMMRegister dst, XMMRegister src, int vlen_in_bytes, BasicType elem_bt); void load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes); + // vector compare + void vpcmpu(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, + XMMRegister vtmp1, XMMRegister vtmp2, Register scratch); + void vpcmpu32(BasicType typ, XMMRegister dst, XMMRegister src1, XMMRegister src2, ComparisonPredicate comparison, int vlen_in_bytes, + XMMRegister vtmp1, XMMRegister vtmp2, XMMRegister vtmp3, Register scratch); + // Reductions for vectors of bytes, shorts, ints, longs, floats, and doubles. // dst = src1 reduce(op, src2) using vtmp as temps diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index c4c1fe89ade..0b525f55315 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -4245,42 +4245,42 @@ void MacroAssembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, } void MacroAssembler::evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg) { + int comparison, bool is_signed, int vector_len, Register scratch_reg) { if (reachable(src)) { - Assembler::evpcmpd(kdst, mask, nds, as_Address(src), comparison, vector_len); + Assembler::evpcmpd(kdst, mask, nds, as_Address(src), comparison, is_signed, vector_len); } else { lea(scratch_reg, src); - Assembler::evpcmpd(kdst, mask, nds, Address(scratch_reg, 0), comparison, vector_len); + Assembler::evpcmpd(kdst, mask, nds, Address(scratch_reg, 0), comparison, is_signed, vector_len); } } void MacroAssembler::evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg) { + int comparison, bool is_signed, int vector_len, Register scratch_reg) { if (reachable(src)) { - Assembler::evpcmpq(kdst, mask, nds, as_Address(src), comparison, vector_len); + Assembler::evpcmpq(kdst, mask, nds, as_Address(src), comparison, is_signed, vector_len); } else { lea(scratch_reg, src); - Assembler::evpcmpq(kdst, mask, nds, Address(scratch_reg, 0), comparison, vector_len); + Assembler::evpcmpq(kdst, mask, nds, Address(scratch_reg, 0), comparison, is_signed, vector_len); } } void MacroAssembler::evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg) { + int comparison, bool is_signed, int vector_len, Register scratch_reg) { if (reachable(src)) { - Assembler::evpcmpb(kdst, mask, nds, as_Address(src), comparison, vector_len); + Assembler::evpcmpb(kdst, mask, nds, as_Address(src), comparison, is_signed, vector_len); } else { lea(scratch_reg, src); - Assembler::evpcmpb(kdst, mask, nds, Address(scratch_reg, 0), comparison, vector_len); + Assembler::evpcmpb(kdst, mask, nds, Address(scratch_reg, 0), comparison, is_signed, vector_len); } } void MacroAssembler::evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg) { + int comparison, bool is_signed, int vector_len, Register scratch_reg) { if (reachable(src)) { - Assembler::evpcmpw(kdst, mask, nds, as_Address(src), comparison, vector_len); + Assembler::evpcmpw(kdst, mask, nds, as_Address(src), comparison, is_signed, vector_len); } else { lea(scratch_reg, src); - Assembler::evpcmpw(kdst, mask, nds, Address(scratch_reg, 0), comparison, vector_len); + Assembler::evpcmpw(kdst, mask, nds, Address(scratch_reg, 0), comparison, is_signed, vector_len); } } @@ -10336,7 +10336,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le kmovdl(mask2, result); evmovdquw(tmp1Reg, mask2, Address(src, 0), /*merge*/ false, Assembler::AVX_512bit); - evpcmpuw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); + evpcmpw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, /*signed*/ false, Assembler::AVX_512bit); ktestd(mask1, mask2); jcc(Assembler::carryClear, return_zero); @@ -10386,7 +10386,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le kmovdl(mask2, result); evmovdquw(tmp1Reg, mask2, Address(src, 0), /*merge*/ false, Assembler::AVX_512bit); - evpcmpuw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); + evpcmpw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, /*signed*/ false, Assembler::AVX_512bit); ktestd(mask1, mask2); jcc(Assembler::carryClear, return_zero); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index f74151200dc..735083a64a9 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -1315,21 +1315,21 @@ class MacroAssembler: public Assembler { // Vector compares void evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { Assembler::evpcmpd(kdst, mask, nds, src, comparison, vector_len); } + int comparison, bool is_signed, int vector_len) { Assembler::evpcmpd(kdst, mask, nds, src, comparison, is_signed, vector_len); } void evpcmpd(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg); + int comparison, bool is_signed, int vector_len, Register scratch_reg); void evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { Assembler::evpcmpq(kdst, mask, nds, src, comparison, vector_len); } + int comparison, bool is_signed, int vector_len) { Assembler::evpcmpq(kdst, mask, nds, src, comparison, is_signed, vector_len); } void evpcmpq(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg); + int comparison, bool is_signed, int vector_len, Register scratch_reg); void evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { Assembler::evpcmpb(kdst, mask, nds, src, comparison, vector_len); } + int comparison, bool is_signed, int vector_len) { Assembler::evpcmpb(kdst, mask, nds, src, comparison, is_signed, vector_len); } void evpcmpb(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg); + int comparison, bool is_signed, int vector_len, Register scratch_reg); void evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, XMMRegister src, - int comparison, int vector_len) { Assembler::evpcmpw(kdst, mask, nds, src, comparison, vector_len); } + int comparison, bool is_signed, int vector_len) { Assembler::evpcmpw(kdst, mask, nds, src, comparison, is_signed, vector_len); } void evpcmpw(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, - int comparison, int vector_len, Register scratch_reg); + int comparison, bool is_signed, int vector_len, Register scratch_reg); // Emit comparison instruction for the specified comparison predicate. diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 6d3b96cf136..c80277a0cff 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1403,6 +1403,10 @@ static inline Assembler::AvxVectorLen vector_length_encoding(const MachNode* use return vector_length_encoding(def); } +static inline bool is_unsigned_booltest_pred(int bt) { + return ((bt & BoolTest::unsigned_compare) == BoolTest::unsigned_compare); +} + %} // end source_hpp source %{ @@ -1970,6 +1974,24 @@ bool Matcher::supports_vector_variable_shifts(void) { return (UseAVX >= 2); } +// Does the CPU supports vector unsigned comparison instructions? +const bool Matcher::supports_vector_comparison_unsigned(int vlen, BasicType bt) { + int vlen_in_bytes = vlen * type2aelembytes(bt); + if ((UseAVX > 2) && (VM_Version::supports_avx512vl() || vlen_in_bytes == 64)) + return true; + else { + // instruction set supports only signed comparison + // so need to zero extend to higher integral type and perform comparison + // cannot cast long to higher integral type + // and on avx1 cannot cast 128 bit integral vectors to higher size + + if ((bt != T_LONG) && + ((UseAVX >= 2) || (vlen_in_bytes <= 8))) + return true; + } + return false; +} + const bool Matcher::has_predicated_vectors(void) { bool ret_value = false; if (UseAVX > 2) { @@ -2154,12 +2176,22 @@ void Compile::reshape_address(AddPNode* addp) { static inline Assembler::ComparisonPredicate booltest_pred_to_comparison_pred(int bt) { switch (bt) { - case BoolTest::eq: return Assembler::eq; - case BoolTest::ne: return Assembler::neq; - case BoolTest::le: return Assembler::le; - case BoolTest::ge: return Assembler::nlt; - case BoolTest::lt: return Assembler::lt; - case BoolTest::gt: return Assembler::nle; + case BoolTest::eq: + return Assembler::eq; + case BoolTest::ne: + return Assembler::neq; + case BoolTest::le: + case BoolTest::ule: + return Assembler::le; + case BoolTest::ge: + case BoolTest::uge: + return Assembler::nlt; + case BoolTest::lt: + case BoolTest::ult: + return Assembler::lt; + case BoolTest::gt: + case BoolTest::ugt: + return Assembler::nle; default : ShouldNotReachHere(); return Assembler::_false; } } @@ -6937,7 +6969,9 @@ instruct evcmpFD(vec dst, vec src1, vec src2, immI8 cond, rRegP scratch, kReg kt %} instruct vcmp(legVec dst, legVec src1, legVec src2, immI8 cond, rRegP scratch) %{ - predicate(vector_length_in_bytes(n->in(1)->in(1)) >= 8 && // src1 + predicate((UseAVX <= 2 || !VM_Version::supports_avx512vl()) && + !is_unsigned_booltest_pred(n->in(2)->get_int()) && + vector_length_in_bytes(n->in(1)->in(1)) >= 8 && // src1 vector_length_in_bytes(n->in(1)->in(1)) <= 32 && // src1 is_integral_type(vector_element_basic_type(n->in(1)->in(1)))); // src1 match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); @@ -6952,43 +6986,82 @@ instruct vcmp(legVec dst, legVec src1, legVec src2, immI8 cond, rRegP scratch) % ins_pipe( pipe_slow ); %} -instruct evcmp(vec dst, vec src1, vec src2, immI8 cond, rRegP scratch, kReg ktmp) %{ - predicate(vector_length_in_bytes(n->in(1)->in(1)) == 64 && // src1 +instruct vcmpu(legVec dst, legVec src1, legVec src2, immI8 cond, legVec vtmp1, legVec vtmp2, rRegP scratch) %{ + predicate((UseAVX == 2 || !VM_Version::supports_avx512vl()) && + is_unsigned_booltest_pred(n->in(2)->get_int()) && + vector_length_in_bytes(n->in(1)->in(1)) >= 8 && // src1 + vector_length_in_bytes(n->in(1)->in(1)) <= 16 && // src1 + is_integral_type(vector_element_basic_type(n->in(1)->in(1)))); // src1 + match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); + effect(TEMP vtmp1, TEMP vtmp2, TEMP scratch); + format %{ "vector_compareu $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} + ins_encode %{ + int vlen = vector_length_in_bytes(this, $src1); + Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); + BasicType bt = vector_element_basic_type(this, $src1); + __ vpcmpu(bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen, $vtmp1$$XMMRegister, + $vtmp2$$XMMRegister, $scratch$$Register); + %} + ins_pipe( pipe_slow ); +%} + +instruct vcmpu32(legVec dst, legVec src1, legVec src2, immI8 cond, legVec vtmp1, legVec vtmp2, legVec vtmp3, rRegP scratch) %{ + predicate((UseAVX == 2 || !VM_Version::supports_avx512vl()) && + is_unsigned_booltest_pred(n->in(2)->get_int()) && + vector_length_in_bytes(n->in(1)->in(1)) == 32 && // src1 is_integral_type(vector_element_basic_type(n->in(1)->in(1)))); // src1 match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); + effect(TEMP dst, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP scratch); + format %{ "vector_compareu $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} + ins_encode %{ + int vlen = vector_length_in_bytes(this, $src1); + Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); + BasicType bt = vector_element_basic_type(this, $src1); + __ vpcmpu32(bt, $dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen, $vtmp1$$XMMRegister, + $vtmp2$$XMMRegister, $vtmp3$$XMMRegister, $scratch$$Register); + %} + ins_pipe( pipe_slow ); +%} + +instruct evcmp(vec dst, vec src1, vec src2, immI8 cond, rRegP scratch, kReg ktmp) %{ + predicate(UseAVX > 2 && + (VM_Version::supports_avx512vl() || + vector_length_in_bytes(n->in(1)->in(1)) == 64) && // src1 + is_integral_type(vector_element_basic_type(n->in(1)->in(1)))); // src1 + match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); effect(TEMP scratch, TEMP ktmp); format %{ "vector_compare $dst,$src1,$src2,$cond\t! using $scratch as TEMP" %} ins_encode %{ assert(UseAVX > 2, "required"); - int vlen_enc = Assembler::AVX_512bit; + int vlen_enc = vector_length_encoding(this, $src1); Assembler::ComparisonPredicate cmp = booltest_pred_to_comparison_pred($cond$$constant); + bool is_unsigned = is_unsigned_booltest_pred($cond$$constant); KRegister mask = k0; // The comparison itself is not being masked. bool merge = false; BasicType src1_elem_bt = vector_element_basic_type(this, $src1); switch (src1_elem_bt) { case T_BYTE: { - __ evpcmpb($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen_enc); + __ evpcmpb($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, !is_unsigned, vlen_enc); __ evmovdqub($dst$$XMMRegister, $ktmp$$KRegister, ExternalAddress(vector_all_bits_set()), merge, vlen_enc, $scratch$$Register); break; } case T_SHORT: { - __ evpcmpw($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen_enc); + __ evpcmpw($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, !is_unsigned, vlen_enc); __ evmovdquw($dst$$XMMRegister, $ktmp$$KRegister, ExternalAddress(vector_all_bits_set()), merge, vlen_enc, $scratch$$Register); break; } case T_INT: { - __ evpcmpd($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen_enc); + __ evpcmpd($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, !is_unsigned, vlen_enc); __ evmovdqul($dst$$XMMRegister, $ktmp$$KRegister, ExternalAddress(vector_all_bits_set()), merge, vlen_enc, $scratch$$Register); break; } case T_LONG: { - __ evpcmpq($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, vlen_enc); + __ evpcmpq($ktmp$$KRegister, mask, $src1$$XMMRegister, $src2$$XMMRegister, cmp, !is_unsigned, vlen_enc); __ evmovdquq($dst$$XMMRegister, $ktmp$$KRegister, ExternalAddress(vector_all_bits_set()), merge, vlen_enc, $scratch$$Register); break; } - default: assert(false, "%s", type2name(src1_elem_bt)); } %} diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index b0d36c7b5d2..1a65fc36ce3 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -315,6 +315,7 @@ class Matcher : public PhaseTransform { static const bool match_rule_supported_vector(int opcode, int vlen, BasicType bt); // Some microarchitectures have mask registers used on vectors + static const bool supports_vector_comparison_unsigned(int vlen, BasicType bt); static const bool has_predicated_vectors(void); static const RegMask* predicate_reg_mask(void); static const TypeVect* predicate_reg_type(const Type* elemTy, int length); diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index 2358cdd54f7..dc2c2299dd3 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -280,10 +280,15 @@ class CmpD3Node : public CmpDNode { // Convert condition codes to a boolean test value (0 or -1). // We pick the values as 3 bits; the low order 2 bits we compare against the // condition codes, the high bit flips the sense of the result. +// For vector compares, additionally, the 4th bit indicates if the compare is unsigned struct BoolTest { - enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 }; + enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8, + // The following values are used with vector compares + // A BoolTest value should not be constructed for such values + unsigned_compare = 16, + ule = unsigned_compare | le, uge = unsigned_compare | ge, ult = unsigned_compare | lt, ugt = unsigned_compare | gt }; mask _test; - BoolTest( mask btm ) : _test(btm) {} + BoolTest( mask btm ) : _test(btm) { assert((btm & unsigned_compare) == 0, "unsupported");} const Type *cc2logical( const Type *CC ) const; // Commute the test. I use a small table lookup. The table is created as // a simple char array where each element is the ASCII version of a 'mask' diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 8d54d95a8d7..4d2e14ac30e 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -608,6 +608,22 @@ bool LibraryCallKit::inline_vector_broadcast_coerced() { return true; } +static bool elem_consistent_with_arr(BasicType elem_bt, const TypeAryPtr* arr_type) { + assert(arr_type != NULL, "unexpected"); + BasicType arr_elem_bt = arr_type->elem()->array_element_basic_type(); + if (elem_bt == arr_elem_bt) { + return true; + } else if (elem_bt == T_SHORT && arr_elem_bt == T_CHAR) { + // Load/store of short vector from/to char[] is supported + return true; + } else if (elem_bt == T_BYTE && arr_elem_bt == T_BOOLEAN) { + // Load/store of byte vector from/to boolean[] is supported + return true; + } else { + return false; + } +} + // > // V load(Class vectorClass, Class elementType, int vlen, // Object base, long offset, @@ -685,7 +701,12 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) { bool using_byte_array = arr_type != NULL && arr_type->elem()->array_element_basic_type() == T_BYTE && elem_bt != T_BYTE; // Handle loading masks. // If there is no consistency between array and vector element types, it must be special byte array case or loading masks - if (arr_type != NULL && !using_byte_array && elem_bt != arr_type->elem()->array_element_basic_type() && !is_mask) { + if (arr_type != NULL && !using_byte_array && !is_mask && !elem_consistent_with_arr(elem_bt, arr_type)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d etype=%s atype=%s ismask=no", + is_store, is_store ? "store" : "load", + num_elem, type2name(elem_bt), type2name(arr_type->elem()->array_element_basic_type())); + } set_map(old_map); set_sp(old_sp); return false; @@ -867,7 +888,12 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) { const TypeAryPtr* arr_type = addr_type->isa_aryptr(); // The array must be consistent with vector type - if (arr_type == NULL || (arr_type != NULL && elem_bt != arr_type->elem()->array_element_basic_type())) { + if (arr_type == NULL || (arr_type != NULL && !elem_consistent_with_arr(elem_bt, arr_type))) { + if (C->print_intrinsics()) { + tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d etype=%s atype=%s ismask=no", + is_scatter, is_scatter ? "scatter" : "gather", + num_elem, type2name(elem_bt), type2name(arr_type->elem()->array_element_basic_type())); + } set_map(old_map); set_sp(old_sp); return false; @@ -1186,6 +1212,16 @@ bool LibraryCallKit::inline_vector_compare() { BasicType elem_bt = elem_type->basic_type(); BasicType mask_bt = elem_bt; + if ((cond->get_con() & BoolTest::unsigned_compare) != 0) { + if (!Matcher::supports_vector_comparison_unsigned(num_elem, elem_bt)) { + if (C->print_intrinsics()) { + tty->print_cr(" ** not supported: unsigned comparison op=comp/%d vlen=%d etype=%s ismask=usestore", + cond->get_con() & (BoolTest::unsigned_compare - 1), num_elem, type2name(elem_bt)); + } + return false; + } + } + if (!arch_supports_vector(Op_VectorMaskCmp, num_elem, elem_bt, VecMaskUseStore)) { if (C->print_intrinsics()) { tty->print_cr(" ** not supported: arity=2 op=comp/%d vlen=%d etype=%s ismask=usestore", diff --git a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java index 7f02c9accce..e7907477afa 100644 --- a/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/vector/VectorSupport.java @@ -27,11 +27,7 @@ import jdk.internal.HotSpotIntrinsicCandidate; import jdk.internal.misc.Unsafe; -import jdk.internal.vm.annotation.ForceInline; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.util.Objects; import java.util.function.*; public class VectorSupport { @@ -74,15 +70,24 @@ public class VectorSupport { public static final int VECTOR_OP_MASK_FIRSTTRUE = 20; public static final int VECTOR_OP_MASK_LASTTRUE = 21; - // enum BoolTest - public static final int BT_eq = 0; - public static final int BT_ne = 4; - public static final int BT_le = 5; - public static final int BT_ge = 7; - public static final int BT_lt = 3; - public static final int BT_gt = 1; - public static final int BT_overflow = 2; - public static final int BT_no_overflow = 6; + // See src/hotspot/share/opto/subnode.hpp + // struct BoolTest, and enclosed enum mask + public static final int BT_eq = 0; // 0000 + public static final int BT_ne = 4; // 0100 + public static final int BT_le = 5; // 0101 + public static final int BT_ge = 7; // 0111 + public static final int BT_lt = 3; // 0011 + public static final int BT_gt = 1; // 0001 + public static final int BT_overflow = 2; // 0010 + public static final int BT_no_overflow = 6; // 0110 + // never = 8 1000 + // illegal = 9 1001 + // Unsigned comparisons apply to BT_le, BT_ge, BT_lt, BT_gt for integral types + public static final int BT_unsigned_compare = 0b10000; + public static final int BT_ule = BT_le | BT_unsigned_compare; + public static final int BT_uge = BT_ge | BT_unsigned_compare; + public static final int BT_ult = BT_lt | BT_unsigned_compare; + public static final int BT_ugt = BT_gt | BT_unsigned_compare; // BasicType codes, for primitives only: public static final int diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java index df4ef52bdee..8bd07fdb3bc 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte128Vector.java @@ -841,6 +841,14 @@ ByteVector fromArray0(byte[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline + @Override + final + ByteVector fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java index ee33b9a1830..27ebd9c158e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte256Vector.java @@ -873,6 +873,14 @@ ByteVector fromArray0(byte[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline + @Override + final + ByteVector fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java index e0d14373936..385290ba626 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte512Vector.java @@ -937,6 +937,14 @@ ByteVector fromArray0(byte[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline + @Override + final + ByteVector fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java index 66bc047c547..3020c077365 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Byte64Vector.java @@ -825,6 +825,14 @@ ByteVector fromArray0(byte[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline + @Override + final + ByteVector fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java index 8371e625182..cc4d61b3ac5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteMaxVector.java @@ -811,6 +811,14 @@ ByteVector fromArray0(byte[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline + @Override + final + ByteVector fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java index a50fb8123ff..02fb61d42b4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, byte a, byte b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract ByteSpecies vspecies(); @@ -1776,6 +1762,10 @@ boolean compareWithOp(int cond, byte a, byte b) { case BT_le: return a <= b; case BT_gt: return a > b; case BT_ge: return a >= b; + case BT_ult: return Byte.compareUnsigned(a, b) < 0; + case BT_ule: return Byte.compareUnsigned(a, b) <= 0; + case BT_ugt: return Byte.compareUnsigned(a, b) > 0; + case BT_uge: return Byte.compareUnsigned(a, b) >= 0; } throw new AssertionError(); } @@ -2835,6 +2825,165 @@ ByteVector fromArray(VectorSpecies species, return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]); } + + /** + * Loads a vector from an array of type {@code boolean[]} + * starting at an offset. + * For each vector lane, where {@code N} is the vector lane index, the + * array element at index {@code offset + N} + * is first converted to a {@code byte} value and then + * placed into the resulting vector at lane index {@code N}. + *

+ * A {@code boolean} value is converted to a {@code byte} value by applying the + * expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array + * @return the vector loaded from an array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public static + ByteVector fromBooleanArray(VectorSpecies species, + boolean[] a, int offset) { + offset = checkFromIndexSize(offset, species.length(), a.length); + ByteSpecies vsp = (ByteSpecies) species; + return vsp.dummyVector().fromBooleanArray0(a, offset); + } + + /** + * Loads a vector from an array of type {@code boolean[]} + * starting at an offset and using a mask. + * Lanes where the mask is unset are filled with the default + * value of {@code byte} (zero). + * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then the array element at + * index {@code offset + N} + * is first converted to a {@code byte} value and then + * placed into the resulting vector at lane index + * {@code N}, otherwise the default element value is placed into the + * resulting vector at lane index {@code N}. + *

+ * A {@code boolean} value is converted to a {@code byte} value by applying the + * expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array + * @param m the mask controlling lane selection + * @return the vector loaded from an array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public static + ByteVector fromBooleanArray(VectorSpecies species, + boolean[] a, int offset, + VectorMask m) { + ByteSpecies vsp = (ByteSpecies) species; + if (offset >= 0 && offset <= (a.length - species.length())) { + ByteVector zero = vsp.zero(); + return zero.blend(zero.fromBooleanArray0(a, offset), m); + } + + // FIXME: optimize + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + return vsp.vOp(m, i -> (byte) (a[offset + i] ? 1 : 0)); + } + + /** + * Gathers a new vector composed of elements from an array of type + * {@code boolean[]}, + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane is loaded from the expression + * {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see ByteVector#toIntArray() + */ + @ForceInline + public static + ByteVector fromBooleanArray(VectorSpecies species, + boolean[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + ByteSpecies vsp = (ByteSpecies) species; + return vsp.vOp(n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0)); + } + + /** + * Gathers a new vector composed of elements from an array of type + * {@code boolean[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the lane is set in the mask, + * the lane is loaded from the expression + * {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * Unset lanes in the resulting vector are set to zero. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask controlling lane selection + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see ByteVector#toIntArray() + */ + @ForceInline + public static + ByteVector fromBooleanArray(VectorSpecies species, + boolean[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask m) { + // FIXME: optimize + ByteSpecies vsp = (ByteSpecies) species; + return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0)); + } + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2961,7 +3110,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code byte} + * Stores this vector into an array of type {@code byte[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3077,6 +3226,174 @@ void intoArray(byte[] a, int offset, }); } + + /** + * Stores this vector into an array of type {@code boolean[]} + * starting at an offset. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array element {@code a[offset+N]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + * + * @param a the array + * @param offset the offset into the array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset) { + offset = checkFromIndexSize(offset, length(), a.length); + ByteSpecies vsp = vspecies(); + ByteVector normalized = this.and((byte) 1); + VectorSupport.store( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, booleanArrayAddress(a, offset), + normalized, + a, offset, + (arr, off, v) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0)); + } + + /** + * Stores this vector into an array of type {@code boolean[]} + * starting at offset and using a mask. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array element {@code a[offset+N]}. + * If the mask lane at {@code N} is unset then the corresponding + * array element {@code a[offset+N]} is left unchanged. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + *

+ * Array range checking is done for lanes where the mask is set. + * Lanes where the mask is unset are not stored and do not need + * to correspond to legitimate elements of {@code a}. + * That is, unset lanes may correspond to array indexes less than + * zero or beyond the end of the array. + * + * @param a the array + * @param offset the offset into the array + * @param m the mask controlling lane storage + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset, + VectorMask m) { + if (m.allTrue()) { + intoBooleanArray(a, offset); + } else { + // FIXME: optimize + ByteSpecies vsp = vspecies(); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + stOp(a, offset, m, (arr, off, i, e) -> arr[off+i] = (e & 1) != 0); + } + } + + /** + * Scatters this vector into an array of type {@code boolean[]} + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see ByteVector#toIntArray() + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + stOp(a, offset, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (e & 1) != 0; + }); + } + + /** + * Scatters this vector into an array of type {@code boolean[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see ByteVector#toIntArray() + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask m) { + // FIXME: optimize + stOp(a, offset, m, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (e & 1) != 0; + }); + } + /** * {@inheritDoc} */ @@ -3183,6 +3500,22 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + + /*package-private*/ + abstract + ByteVector fromBooleanArray0(boolean[] a, int offset); + @ForceInline + final + ByteVector fromBooleanArray0Template(boolean[] a, int offset) { + ByteSpecies vsp = vspecies(); + return VectorSupport.load( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, booleanArrayAddress(a, offset), + a, offset, vsp, + (arr, off, s) -> s.ldOp(arr, off, + (arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0))); + } + @Override abstract ByteVector fromByteArray0(byte[] a, int offset); @@ -3313,6 +3646,17 @@ static long arrayAddress(byte[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + + static final int ARRAY_BOOLEAN_SHIFT = + 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE); + static final long ARRAY_BOOLEAN_BASE = + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; + + @ForceInline + static long booleanArrayAddress(boolean[] a, int index) { + return ARRAY_BOOLEAN_BASE + (((long)index) << ARRAY_BOOLEAN_SHIFT); + } + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java index 948717844e3..c74160c8448 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java @@ -809,6 +809,8 @@ DoubleVector fromArray0(double[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java index da2d5b6795e..22f4534e8f4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java @@ -813,6 +813,8 @@ DoubleVector fromArray0(double[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java index b28ba23d4de..2366d9e9904 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java @@ -821,6 +821,8 @@ DoubleVector fromArray0(double[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java index 846802bea64..4f4c8ff004f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java @@ -807,6 +807,8 @@ DoubleVector fromArray0(double[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java index 96818f30eec..bc8ee9e31c8 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java @@ -806,6 +806,8 @@ DoubleVector fromArray0(double[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java index 7db52e25e10..cdda26138b1 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, double a, double b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract DoubleSpecies vspecies(); @@ -2742,6 +2728,8 @@ DoubleVector fromArray(VectorSpecies species, } } + + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2874,7 +2862,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code double} + * Stores this vector into an array of type {@code double[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3031,6 +3019,8 @@ void intoArray(double[] a, int offset, } } + + /** * {@inheritDoc} */ @@ -3137,6 +3127,8 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + + @Override abstract DoubleVector fromByteArray0(byte[] a, int offset); @@ -3272,6 +3264,8 @@ static long arrayAddress(double[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java index c3bed76826f..34272b587ea 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float128Vector.java @@ -813,6 +813,8 @@ FloatVector fromArray0(float[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java index 01b7002b14c..6cf9420851a 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float256Vector.java @@ -821,6 +821,8 @@ FloatVector fromArray0(float[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java index 3a01e5ab8ad..a75cf65ebf2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float512Vector.java @@ -837,6 +837,8 @@ FloatVector fromArray0(float[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java index 2a0d253d2b0..683c7ba6907 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float64Vector.java @@ -809,6 +809,8 @@ FloatVector fromArray0(float[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java index 14c454e34eb..a3464c7b96f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatMaxVector.java @@ -806,6 +806,8 @@ FloatVector fromArray0(float[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java index 70b94067255..682141ff1df 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, float a, float b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract FloatSpecies vspecies(); @@ -2748,6 +2734,8 @@ FloatVector fromArray(VectorSpecies species, } } + + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2880,7 +2868,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code float} + * Stores this vector into an array of type {@code float[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3018,6 +3006,8 @@ void intoArray(float[] a, int offset, } } + + /** * {@inheritDoc} */ @@ -3124,6 +3114,8 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + + @Override abstract FloatVector fromByteArray0(byte[] a, int offset); @@ -3259,6 +3251,8 @@ static long arrayAddress(float[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java index 43f6e4addbc..80f3c98c186 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int128Vector.java @@ -817,6 +817,8 @@ IntVector fromArray0(int[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java index 2ba20eae8d8..ce67806d0e5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java @@ -825,6 +825,8 @@ IntVector fromArray0(int[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java index e46a52ee224..ceb2893b3e5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int512Vector.java @@ -841,6 +841,8 @@ IntVector fromArray0(int[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java index 1dc9445e687..dd056983113 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int64Vector.java @@ -813,6 +813,8 @@ IntVector fromArray0(int[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java index 3cdadefef0a..f65fd251b24 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntMaxVector.java @@ -822,6 +822,8 @@ IntVector fromArray0(int[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java index f6fa9df9d4d..5c3ae0058a3 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, int a, int b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract IntSpecies vspecies(); @@ -1775,6 +1761,10 @@ boolean compareWithOp(int cond, int a, int b) { case BT_le: return a <= b; case BT_gt: return a > b; case BT_ge: return a >= b; + case BT_ult: return Integer.compareUnsigned(a, b) < 0; + case BT_ule: return Integer.compareUnsigned(a, b) <= 0; + case BT_ugt: return Integer.compareUnsigned(a, b) > 0; + case BT_uge: return Integer.compareUnsigned(a, b) >= 0; } throw new AssertionError(); } @@ -2851,6 +2841,8 @@ IntVector fromArray(VectorSpecies species, } } + + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2983,7 +2975,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code int} + * Stores this vector into an array of type {@code int[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3121,6 +3113,8 @@ void intoArray(int[] a, int offset, } } + + /** * {@inheritDoc} */ @@ -3227,6 +3221,8 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + + @Override abstract IntVector fromByteArray0(byte[] a, int offset); @@ -3362,6 +3358,8 @@ static long arrayAddress(int[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java index d5e95b9af5c..69b6fd31c3f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java @@ -803,6 +803,8 @@ LongVector fromArray0(long[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java index d1a5bc294a1..80873cce5b8 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java @@ -807,6 +807,8 @@ LongVector fromArray0(long[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java index c07bfe6618f..b830d8bc62c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java @@ -815,6 +815,8 @@ LongVector fromArray0(long[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java index a4cd546165c..2beeff529b5 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java @@ -801,6 +801,8 @@ LongVector fromArray0(long[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java index 38ae94aa96f..4fa300a45e6 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java @@ -801,6 +801,8 @@ LongVector fromArray0(long[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java index 2283b3c8ec2..5d5c65a1f14 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, long a, long b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract LongSpecies vspecies(); @@ -1693,6 +1679,10 @@ boolean compareWithOp(int cond, long a, long b) { case BT_le: return a <= b; case BT_gt: return a > b; case BT_ge: return a >= b; + case BT_ult: return Long.compareUnsigned(a, b) < 0; + case BT_ule: return Long.compareUnsigned(a, b) <= 0; + case BT_ugt: return Long.compareUnsigned(a, b) > 0; + case BT_uge: return Long.compareUnsigned(a, b) >= 0; } throw new AssertionError(); } @@ -2735,6 +2725,8 @@ LongVector fromArray(VectorSpecies species, } } + + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2867,7 +2859,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code long} + * Stores this vector into an array of type {@code long[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3024,6 +3016,8 @@ void intoArray(long[] a, int offset, } } + + /** * {@inheritDoc} */ @@ -3130,6 +3124,8 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + + @Override abstract LongVector fromByteArray0(byte[] a, int offset); @@ -3265,6 +3261,8 @@ static long arrayAddress(long[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java index 1ae152c5990..f1ee2cd397c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short128Vector.java @@ -825,6 +825,14 @@ ShortVector fromArray0(short[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + @ForceInline + @Override + final + ShortVector fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java index bf997f0ea82..2d2860e1679 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short256Vector.java @@ -841,6 +841,14 @@ ShortVector fromArray0(short[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + @ForceInline + @Override + final + ShortVector fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java index 1a9d959d8e5..87f8e64e30d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short512Vector.java @@ -873,6 +873,14 @@ ShortVector fromArray0(short[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + @ForceInline + @Override + final + ShortVector fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java index 6a511b29fe1..f580d0020bd 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Short64Vector.java @@ -817,6 +817,14 @@ ShortVector fromArray0(short[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + @ForceInline + @Override + final + ShortVector fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java index 617b3e91c02..08c170047d0 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortMaxVector.java @@ -811,6 +811,14 @@ ShortVector fromArray0(short[] a, int offset) { return super.fromArray0Template(a, offset); // specialize } + @ForceInline + @Override + final + ShortVector fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } + + @ForceInline @Override final diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java index 022653cefd7..63374480883 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java @@ -379,20 +379,6 @@ AbstractMask bTest(int cond, return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, short a, short b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract ShortSpecies vspecies(); @@ -1776,6 +1762,10 @@ boolean compareWithOp(int cond, short a, short b) { case BT_le: return a <= b; case BT_gt: return a > b; case BT_ge: return a >= b; + case BT_ult: return Short.compareUnsigned(a, b) < 0; + case BT_ule: return Short.compareUnsigned(a, b) <= 0; + case BT_ugt: return Short.compareUnsigned(a, b) > 0; + case BT_uge: return Short.compareUnsigned(a, b) >= 0; } throw new AssertionError(); } @@ -2835,6 +2825,159 @@ ShortVector fromArray(VectorSpecies species, return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]); } + /** + * Loads a vector from an array of type {@code char[]} + * starting at an offset. + * For each vector lane, where {@code N} is the vector lane index, the + * array element at index {@code offset + N} + * is first cast to a {@code short} value and then + * placed into the resulting vector at lane index {@code N}. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array + * @return the vector loaded from an array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public static + ShortVector fromCharArray(VectorSpecies species, + char[] a, int offset) { + offset = checkFromIndexSize(offset, species.length(), a.length); + ShortSpecies vsp = (ShortSpecies) species; + return vsp.dummyVector().fromCharArray0(a, offset); + } + + /** + * Loads a vector from an array of type {@code char[]} + * starting at an offset and using a mask. + * Lanes where the mask is unset are filled with the default + * value of {@code short} (zero). + * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then the array element at + * index {@code offset + N} + * is first cast to a {@code short} value and then + * placed into the resulting vector at lane index + * {@code N}, otherwise the default element value is placed into the + * resulting vector at lane index {@code N}. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array + * @param m the mask controlling lane selection + * @return the vector loaded from an array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public static + ShortVector fromCharArray(VectorSpecies species, + char[] a, int offset, + VectorMask m) { + ShortSpecies vsp = (ShortSpecies) species; + if (offset >= 0 && offset <= (a.length - species.length())) { + ShortVector zero = vsp.zero(); + return zero.blend(zero.fromCharArray0(a, offset), m); + } + + // FIXME: optimize + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + return vsp.vOp(m, i -> (short) a[offset + i]); + } + + /** + * Gathers a new vector composed of elements from an array of type + * {@code char[]}, + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane is loaded from the expression + * {@code (short) a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see ShortVector#toIntArray() + */ + @ForceInline + public static + ShortVector fromCharArray(VectorSpecies species, + char[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + ShortSpecies vsp = (ShortSpecies) species; + return vsp.vOp(n -> (short) a[offset + indexMap[mapOffset + n]]); + } + + /** + * Gathers a new vector composed of elements from an array of type + * {@code char[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the lane is set in the mask, + * the lane is loaded from the expression + * {@code (short) a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * Unset lanes in the resulting vector are set to zero. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask controlling lane selection + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see ShortVector#toIntArray() + */ + @ForceInline + public static + ShortVector fromCharArray(VectorSpecies species, + char[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask m) { + // FIXME: optimize + ShortSpecies vsp = (ShortSpecies) species; + return vsp.vOp(m, n -> (short) a[offset + indexMap[mapOffset + n]]); + } + + /** * Loads a vector from a {@linkplain ByteBuffer byte buffer} * starting at an offset into the byte buffer. @@ -2967,7 +3110,7 @@ a, arrayAddress(a, offset), } /** - * Stores this vector into an array of {@code short} + * Stores this vector into an array of type {@code short[]} * starting at offset and using a mask. *

* For each vector lane, where {@code N} is the vector lane index, @@ -3083,6 +3226,161 @@ void intoArray(short[] a, int offset, }); } + /** + * Stores this vector into an array of type {@code char[]} + * starting at an offset. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array element {@code a[offset+N]}. + * + * @param a the array, of type {@code char[]} + * @param offset the offset into the array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset) { + offset = checkFromIndexSize(offset, length(), a.length); + ShortSpecies vsp = vspecies(); + VectorSupport.store( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, charArrayAddress(a, offset), + this, + a, offset, + (arr, off, v) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> arr_[off_ + i] = (char) e)); + } + + /** + * Stores this vector into an array of type {@code char[]} + * starting at offset and using a mask. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array element {@code a[offset+N]}. + * If the mask lane at {@code N} is unset then the corresponding + * array element {@code a[offset+N]} is left unchanged. + *

+ * Array range checking is done for lanes where the mask is set. + * Lanes where the mask is unset are not stored and do not need + * to correspond to legitimate elements of {@code a}. + * That is, unset lanes may correspond to array indexes less than + * zero or beyond the end of the array. + * + * @param a the array, of type {@code char[]} + * @param offset the offset into the array + * @param m the mask controlling lane storage + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset, + VectorMask m) { + if (m.allTrue()) { + intoCharArray(a, offset); + } else { + // FIXME: optimize + ShortSpecies vsp = vspecies(); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = (char) v); + } + } + + /** + * Scatters this vector into an array of type {@code char[]} + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see ShortVector#toIntArray() + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + stOp(a, offset, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (char) e; + }); + } + + /** + * Scatters this vector into an array of type {@code char[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see ShortVector#toIntArray() + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask m) { + // FIXME: optimize + stOp(a, offset, m, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (char) e; + }); + } + + /** * {@inheritDoc} */ @@ -3189,6 +3487,22 @@ a, arrayAddress(a, offset), (arr_, off_, i) -> arr_[off_ + i])); } + /*package-private*/ + abstract + ShortVector fromCharArray0(char[] a, int offset); + @ForceInline + final + ShortVector fromCharArray0Template(char[] a, int offset) { + ShortSpecies vsp = vspecies(); + return VectorSupport.load( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, charArrayAddress(a, offset), + a, offset, vsp, + (arr, off, s) -> s.ldOp(arr, off, + (arr_, off_, i) -> (short) arr_[off_ + i])); + } + + @Override abstract ShortVector fromByteArray0(byte[] a, int offset); @@ -3324,6 +3638,17 @@ static long arrayAddress(short[] a, int index) { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } + static final int ARRAY_CHAR_SHIFT = + 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_CHAR_INDEX_SCALE); + static final long ARRAY_CHAR_BASE = + Unsafe.ARRAY_CHAR_BASE_OFFSET; + + @ForceInline + static long charArrayAddress(char[] a, int index) { + return ARRAY_CHAR_BASE + (((long)index) << ARRAY_CHAR_SHIFT); + } + + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java index 69a8980f626..d37066e6ff7 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Vector.java @@ -240,13 +240,13 @@ * each distinct lane of the input vector. If there are additional * vector arguments of the same type, their lanes are aligned with the * lanes of the first input vector. (They must all have a common - * {@code VLENGTH}.) The output resulting from a lane-wise operation - * will have a {@code VLENGTH} which is equal to the {@code VLENGTH} - * of the input(s) to the operation. Thus, lane-wise operations are - * length-invariant, in their basic definitions. + * {@code VLENGTH}.) For most lane-wise operations, the output resulting + * from a lane-wise operation will have a {@code VLENGTH} which is equal to + * the {@code VLENGTH} of the input(s) to the operation. Thus, such lane-wise + * operations are length-invariant, in their basic definitions. * *

The principle of length-invariance is combined with another - * basic principle, that lane-wise operations are always + * basic principle, that most length-invariant lane-wise operations are also * shape-invariant, meaning that the inputs and the output of * a lane-wise operation will have a common {@code VSHAPE}. When the * principles conflict, because a logical result (with an invariant @@ -799,7 +799,8 @@ * approach to the design of such resizing vector operations. * *

As a basic principle, lane-wise operations are - * length-invariant. Length-invariance simply means that + * length-invariant, unless clearly marked otherwise. + * Length-invariance simply means that * if {@code VLENGTH} lanes go into an operation, the same number * of lanes come out, with nothing discarded and no extra padding. * diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java index 4a5f89da0a5..222de9db793 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java @@ -565,7 +565,26 @@ static boolean opKind(Operator op, int bit) { public static final Comparison GT = compare("GT", ">", VectorSupport.BT_gt, VO_ALL); /** Compare {@code a>=b}. */ public static final Comparison GE = compare("GE", ">=", VectorSupport.BT_ge, VO_ALL); - // FIXME: add unsigned comparisons + /** Unsigned compare {@code a", VectorSupport.BT_ugt, VO_NOFP); + /** Unsigned compare {@code a>=b}. Integral only. + * @see java.lang.Integer#compareUnsigned + * @see java.lang.Long#compareUnsigned + */ + public static final Comparison UNSIGNED_GE = compare("UNSIGNED_GE", ">=", VectorSupport.BT_uge, VO_NOFP); // Conversion operators diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template index 26391abfb7e..ea23266cfba 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template @@ -383,20 +383,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { return maskFactory(bits); } - /*package-private*/ - @ForceInline - static boolean doBinTest(int cond, $type$ a, $type$ b) { - switch (cond) { - case BT_eq: return a == b; - case BT_ne: return a != b; - case BT_lt: return a < b; - case BT_le: return a <= b; - case BT_gt: return a > b; - case BT_ge: return a >= b; - } - throw new AssertionError(Integer.toHexString(cond)); - } - /*package-private*/ @Override abstract $Type$Species vspecies(); @@ -2041,6 +2027,12 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { case BT_le: return a <= b; case BT_gt: return a > b; case BT_ge: return a >= b; +#if[!FP] + case BT_ult: return $Boxtype$.compareUnsigned(a, b) < 0; + case BT_ule: return $Boxtype$.compareUnsigned(a, b) <= 0; + case BT_ugt: return $Boxtype$.compareUnsigned(a, b) > 0; + case BT_uge: return $Boxtype$.compareUnsigned(a, b) >= 0; +#end[!FP] } throw new AssertionError(); } @@ -3375,183 +3367,234 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } #end[byteOrShort] +#if[short] /** - * Loads a vector from a {@linkplain ByteBuffer byte buffer} - * starting at an offset into the byte buffer. - * Bytes are composed into primitive lane elements according - * to the specified byte order. - * The vector is arranged into lanes according to - * memory ordering. - *

- * This method behaves as if it returns the result of calling - * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) - * fromByteBuffer()} as follows: - *

{@code
-     * var m = species.maskAll(true);
-     * return fromByteBuffer(species, bb, offset, bo, m);
-     * }
+ * Loads a vector from an array of type {@code char[]} + * starting at an offset. + * For each vector lane, where {@code N} is the vector lane index, the + * array element at index {@code offset + N} + * is first cast to a {@code short} value and then + * placed into the resulting vector at lane index {@code N}. * * @param species species of desired vector - * @param bb the byte buffer - * @param offset the offset into the byte buffer - * @param bo the intended byte order - * @return a vector loaded from a byte buffer + * @param a the array + * @param offset the offset into the array + * @return the vector loaded from an array * @throws IndexOutOfBoundsException - * if {@code offset+N*$sizeInBytes$ < 0} - * or {@code offset+N*$sizeInBytes$ >= bb.limit()} + * if {@code offset+N < 0} or {@code offset+N >= a.length} * for any lane {@code N} in the vector */ @ForceInline public static - $abstractvectortype$ fromByteBuffer(VectorSpecies<$Boxtype$> species, - ByteBuffer bb, int offset, - ByteOrder bo) { - offset = checkFromIndexSize(offset, species.vectorByteSize(), bb.limit()); + $abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species, + char[] a, int offset) { + offset = checkFromIndexSize(offset, species.length(), a.length); $Type$Species vsp = ($Type$Species) species; - return vsp.dummyVector().fromByteBuffer0(bb, offset).maybeSwap(bo); + return vsp.dummyVector().fromCharArray0(a, offset); } /** - * Loads a vector from a {@linkplain ByteBuffer byte buffer} - * starting at an offset into the byte buffer - * and using a mask. + * Loads a vector from an array of type {@code char[]} + * starting at an offset and using a mask. * Lanes where the mask is unset are filled with the default * value of {@code $type$} ({#if[FP]?positive }zero). - * Bytes are composed into primitive lane elements according - * to the specified byte order. - * The vector is arranged into lanes according to - * memory ordering. - *

- * The following pseudocode illustrates the behavior: - *

{@code
-     * $Type$Buffer eb = bb.duplicate()
-     *     .position(offset){#if[byte]?;}
-#if[!byte]
-     *     .order(bo).as$Type$Buffer();
-#end[!byte]
-     * $type$[] ar = new $type$[species.length()];
-     * for (int n = 0; n < ar.length; n++) {
-     *     if (m.laneIsSet(n)) {
-     *         ar[n] = eb.get(n);
-     *     }
-     * }
-     * $abstractvectortype$ r = $abstractvectortype$.fromArray(species, ar, 0);
-     * }
- * @implNote -#if[!byte] - * This operation is likely to be more efficient if - * the specified byte order is the same as - * {@linkplain ByteOrder#nativeOrder() - * the platform native order}, - * since this method will not need to reorder - * the bytes of lane values. -#else[!byte] - * The byte order argument is ignored. -#end[!byte] + * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then the array element at + * index {@code offset + N} + * is first cast to a {@code short} value and then + * placed into the resulting vector at lane index + * {@code N}, otherwise the default element value is placed into the + * resulting vector at lane index {@code N}. * * @param species species of desired vector - * @param bb the byte buffer - * @param offset the offset into the byte buffer - * @param bo the intended byte order + * @param a the array + * @param offset the offset into the array * @param m the mask controlling lane selection - * @return a vector loaded from a byte buffer + * @return the vector loaded from an array * @throws IndexOutOfBoundsException - * if {@code offset+N*$sizeInBytes$ < 0} - * or {@code offset+N*$sizeInBytes$ >= bb.limit()} + * if {@code offset+N < 0} or {@code offset+N >= a.length} * for any lane {@code N} in the vector * where the mask is set */ @ForceInline public static - $abstractvectortype$ fromByteBuffer(VectorSpecies<$Boxtype$> species, - ByteBuffer bb, int offset, - ByteOrder bo, - VectorMask<$Boxtype$> m) { + $abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species, + char[] a, int offset, + VectorMask<$Boxtype$> m) { $Type$Species vsp = ($Type$Species) species; - if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) { + if (offset >= 0 && offset <= (a.length - species.length())) { $abstractvectortype$ zero = vsp.zero(); - $abstractvectortype$ v = zero.fromByteBuffer0(bb, offset); - return zero.blend(v.maybeSwap(bo), m); + return zero.blend(zero.fromCharArray0(a, offset), m); } // FIXME: optimize - checkMaskFromIndexSize(offset, vsp, m, $sizeInBytes$, bb.limit()); - ByteBuffer wb = wrapper(bb, bo); - return vsp.ldOp(wb, offset, (AbstractMask<$Boxtype$>)m, - (wb_, o, i) -> wb_.get{#if[byte]?(:$Type$(}o + i * $sizeInBytes$)); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + return vsp.vOp(m, i -> (short) a[offset + i]); } - // Memory store operations + /** + * Gathers a new vector composed of elements from an array of type + * {@code char[]}, + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane is loaded from the expression + * {@code (short) a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see $abstractvectortype$#toIntArray() + */ + @ForceInline + public static + $abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species, + char[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + $Type$Species vsp = ($Type$Species) species; + return vsp.vOp(n -> (short) a[offset + indexMap[mapOffset + n]]); + } /** - * Stores this vector into an array of type {@code $type$[]} - * starting at an offset. + * Gathers a new vector composed of elements from an array of type + * {@code char[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. *

* For each vector lane, where {@code N} is the vector lane index, - * the lane element at index {@code N} is stored into the array - * element {@code a[offset+N]}. + * if the lane is set in the mask, + * the lane is loaded from the expression + * {@code (short) a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * Unset lanes in the resulting vector are set to zero. * - * @param a the array, of type {@code $type$[]} + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask controlling lane selection + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see $abstractvectortype$#toIntArray() + */ + @ForceInline + public static + $abstractvectortype$ fromCharArray(VectorSpecies<$Boxtype$> species, + char[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + // FIXME: optimize + $Type$Species vsp = ($Type$Species) species; + return vsp.vOp(m, n -> (short) a[offset + indexMap[mapOffset + n]]); + } +#end[short] + +#if[byte] + /** + * Loads a vector from an array of type {@code boolean[]} + * starting at an offset. + * For each vector lane, where {@code N} is the vector lane index, the + * array element at index {@code offset + N} + * is first converted to a {@code byte} value and then + * placed into the resulting vector at lane index {@code N}. + *

+ * A {@code boolean} value is converted to a {@code byte} value by applying the + * expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value. + * + * @param species species of desired vector + * @param a the array * @param offset the offset into the array + * @return the vector loaded from an array * @throws IndexOutOfBoundsException * if {@code offset+N < 0} or {@code offset+N >= a.length} * for any lane {@code N} in the vector */ @ForceInline - public final - void intoArray($type$[] a, int offset) { - offset = checkFromIndexSize(offset, length(), a.length); - $Type$Species vsp = vspecies(); - VectorSupport.store( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), - a, arrayAddress(a, offset), - this, - a, offset, - (arr, off, v) - -> v.stOp(arr, off, - (arr_, off_, i, e) -> arr_[off_ + i] = e)); + public static + $abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species, + boolean[] a, int offset) { + offset = checkFromIndexSize(offset, species.length(), a.length); + $Type$Species vsp = ($Type$Species) species; + return vsp.dummyVector().fromBooleanArray0(a, offset); } /** - * Stores this vector into an array of {@code $type$} - * starting at offset and using a mask. - *

+ * Loads a vector from an array of type {@code boolean[]} + * starting at an offset and using a mask. + * Lanes where the mask is unset are filled with the default + * value of {@code $type$} ({#if[FP]?positive }zero). * For each vector lane, where {@code N} is the vector lane index, - * the lane element at index {@code N} is stored into the array - * element {@code a[offset+N]}. - * If the mask lane at {@code N} is unset then the corresponding - * array element {@code a[offset+N]} is left unchanged. + * if the mask lane at index {@code N} is set then the array element at + * index {@code offset + N} + * is first converted to a {@code byte} value and then + * placed into the resulting vector at lane index + * {@code N}, otherwise the default element value is placed into the + * resulting vector at lane index {@code N}. *

- * Array range checking is done for lanes where the mask is set. - * Lanes where the mask is unset are not stored and do not need - * to correspond to legitimate elements of {@code a}. - * That is, unset lanes may correspond to array indexes less than - * zero or beyond the end of the array. + * A {@code boolean} value is converted to a {@code byte} value by applying the + * expression {@code (byte) (b ? 1 : 0)}, where {@code b} is the {@code boolean} value. * - * @param a the array, of type {@code $type$[]} + * @param species species of desired vector + * @param a the array * @param offset the offset into the array - * @param m the mask controlling lane storage + * @param m the mask controlling lane selection + * @return the vector loaded from an array * @throws IndexOutOfBoundsException * if {@code offset+N < 0} or {@code offset+N >= a.length} * for any lane {@code N} in the vector * where the mask is set */ @ForceInline - public final - void intoArray($type$[] a, int offset, - VectorMask<$Boxtype$> m) { - if (m.allTrue()) { - intoArray(a, offset); - } else { - // FIXME: optimize - $Type$Species vsp = vspecies(); - checkMaskFromIndexSize(offset, vsp, m, 1, a.length); - stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v); + public static + $abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species, + boolean[] a, int offset, + VectorMask<$Boxtype$> m) { + $Type$Species vsp = ($Type$Species) species; + if (offset >= 0 && offset <= (a.length - species.length())) { + $abstractvectortype$ zero = vsp.zero(); + return zero.blend(zero.fromBooleanArray0(a, offset), m); } + + // FIXME: optimize + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + return vsp.vOp(m, i -> (byte) (a[offset + i] ? 1 : 0)); } /** - * Scatters this vector into an array of type {@code $type$[]} + * Gathers a new vector composed of elements from an array of type + * {@code boolean[]}, * using indexes obtained by adding a fixed {@code offset} to a * series of secondary offsets from an index map. * The index map is a contiguous sequence of {@code VLENGTH} @@ -3559,13 +3602,502 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { * {@code mapOffset}. *

* For each vector lane, where {@code N} is the vector lane index, - * the lane element at index {@code N} is stored into the array - * element {@code a[f(N)]}, where {@code f(N)} is the + * the lane is loaded from the expression + * {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the * index mapping expression * {@code offset + indexMap[mapOffset + N]]}. * + * @param species species of desired vector * @param a the array - * @param offset an offset to combine with the index map offsets + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see $abstractvectortype$#toIntArray() + */ + @ForceInline + public static + $abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species, + boolean[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + $Type$Species vsp = ($Type$Species) species; + return vsp.vOp(n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0)); + } + + /** + * Gathers a new vector composed of elements from an array of type + * {@code boolean[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the lane is set in the mask, + * the lane is loaded from the expression + * {@code (byte) (a[f(N)] ? 1 : 0)}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * Unset lanes in the resulting vector are set to zero. + * + * @param species species of desired vector + * @param a the array + * @param offset the offset into the array, may be negative if relative + * indexes in the index map compensate to produce a value within the + * array bounds + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask controlling lane selection + * @return the vector loaded from the indexed elements of the array + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see $abstractvectortype$#toIntArray() + */ + @ForceInline + public static + $abstractvectortype$ fromBooleanArray(VectorSpecies<$Boxtype$> species, + boolean[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + // FIXME: optimize + $Type$Species vsp = ($Type$Species) species; + return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0)); + } +#end[byte] + + /** + * Loads a vector from a {@linkplain ByteBuffer byte buffer} + * starting at an offset into the byte buffer. + * Bytes are composed into primitive lane elements according + * to the specified byte order. + * The vector is arranged into lanes according to + * memory ordering. + *

+ * This method behaves as if it returns the result of calling + * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) + * fromByteBuffer()} as follows: + *

{@code
+     * var m = species.maskAll(true);
+     * return fromByteBuffer(species, bb, offset, bo, m);
+     * }
+ * + * @param species species of desired vector + * @param bb the byte buffer + * @param offset the offset into the byte buffer + * @param bo the intended byte order + * @return a vector loaded from a byte buffer + * @throws IndexOutOfBoundsException + * if {@code offset+N*$sizeInBytes$ < 0} + * or {@code offset+N*$sizeInBytes$ >= bb.limit()} + * for any lane {@code N} in the vector + */ + @ForceInline + public static + $abstractvectortype$ fromByteBuffer(VectorSpecies<$Boxtype$> species, + ByteBuffer bb, int offset, + ByteOrder bo) { + offset = checkFromIndexSize(offset, species.vectorByteSize(), bb.limit()); + $Type$Species vsp = ($Type$Species) species; + return vsp.dummyVector().fromByteBuffer0(bb, offset).maybeSwap(bo); + } + + /** + * Loads a vector from a {@linkplain ByteBuffer byte buffer} + * starting at an offset into the byte buffer + * and using a mask. + * Lanes where the mask is unset are filled with the default + * value of {@code $type$} ({#if[FP]?positive }zero). + * Bytes are composed into primitive lane elements according + * to the specified byte order. + * The vector is arranged into lanes according to + * memory ordering. + *

+ * The following pseudocode illustrates the behavior: + *

{@code
+     * $Type$Buffer eb = bb.duplicate()
+     *     .position(offset){#if[byte]?;}
+#if[!byte]
+     *     .order(bo).as$Type$Buffer();
+#end[!byte]
+     * $type$[] ar = new $type$[species.length()];
+     * for (int n = 0; n < ar.length; n++) {
+     *     if (m.laneIsSet(n)) {
+     *         ar[n] = eb.get(n);
+     *     }
+     * }
+     * $abstractvectortype$ r = $abstractvectortype$.fromArray(species, ar, 0);
+     * }
+ * @implNote +#if[!byte] + * This operation is likely to be more efficient if + * the specified byte order is the same as + * {@linkplain ByteOrder#nativeOrder() + * the platform native order}, + * since this method will not need to reorder + * the bytes of lane values. +#else[!byte] + * The byte order argument is ignored. +#end[!byte] + * + * @param species species of desired vector + * @param bb the byte buffer + * @param offset the offset into the byte buffer + * @param bo the intended byte order + * @param m the mask controlling lane selection + * @return a vector loaded from a byte buffer + * @throws IndexOutOfBoundsException + * if {@code offset+N*$sizeInBytes$ < 0} + * or {@code offset+N*$sizeInBytes$ >= bb.limit()} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public static + $abstractvectortype$ fromByteBuffer(VectorSpecies<$Boxtype$> species, + ByteBuffer bb, int offset, + ByteOrder bo, + VectorMask<$Boxtype$> m) { + $Type$Species vsp = ($Type$Species) species; + if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) { + $abstractvectortype$ zero = vsp.zero(); + $abstractvectortype$ v = zero.fromByteBuffer0(bb, offset); + return zero.blend(v.maybeSwap(bo), m); + } + + // FIXME: optimize + checkMaskFromIndexSize(offset, vsp, m, $sizeInBytes$, bb.limit()); + ByteBuffer wb = wrapper(bb, bo); + return vsp.ldOp(wb, offset, (AbstractMask<$Boxtype$>)m, + (wb_, o, i) -> wb_.get{#if[byte]?(:$Type$(}o + i * $sizeInBytes$)); + } + + // Memory store operations + + /** + * Stores this vector into an array of type {@code $type$[]} + * starting at an offset. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} is stored into the array + * element {@code a[offset+N]}. + * + * @param a the array, of type {@code $type$[]} + * @param offset the offset into the array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public final + void intoArray($type$[] a, int offset) { + offset = checkFromIndexSize(offset, length(), a.length); + $Type$Species vsp = vspecies(); + VectorSupport.store( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, arrayAddress(a, offset), + this, + a, offset, + (arr, off, v) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> arr_[off_ + i] = e)); + } + + /** + * Stores this vector into an array of type {@code $type$[]} + * starting at offset and using a mask. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} is stored into the array + * element {@code a[offset+N]}. + * If the mask lane at {@code N} is unset then the corresponding + * array element {@code a[offset+N]} is left unchanged. + *

+ * Array range checking is done for lanes where the mask is set. + * Lanes where the mask is unset are not stored and do not need + * to correspond to legitimate elements of {@code a}. + * That is, unset lanes may correspond to array indexes less than + * zero or beyond the end of the array. + * + * @param a the array, of type {@code $type$[]} + * @param offset the offset into the array + * @param m the mask controlling lane storage + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public final + void intoArray($type$[] a, int offset, + VectorMask<$Boxtype$> m) { + if (m.allTrue()) { + intoArray(a, offset); + } else { + // FIXME: optimize + $Type$Species vsp = vspecies(); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v); + } + } + + /** + * Scatters this vector into an array of type {@code $type$[]} + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} is stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see $abstractvectortype$#toIntArray() + */ +#if[byteOrShort] + @ForceInline + public final + void intoArray($type$[] a, int offset, + int[] indexMap, int mapOffset) { + stOp(a, offset, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = e; + }); + } +#else[byteOrShort] + @ForceInline + public final + void intoArray($type$[] a, int offset, + int[] indexMap, int mapOffset) { + $Type$Species vsp = vspecies(); + IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); +#if[longOrDouble] + if (vsp.laneCount() == 1) { + intoArray(a, offset + indexMap[mapOffset]); + return; + } + + // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] + IntVector vix; + if (isp.laneCount() != vsp.laneCount()) { + // For $Type$MaxVector, if vector length is 2048 bits, indexShape + // of $Type$ species is S_MAX_BIT. and the lane count of $Type$ + // vector is 32. When converting $Type$ species to int species, + // indexShape is still S_MAX_BIT, but the lane count of int vector + // is 64. So when loading index vector (IntVector), only lower half + // of index data is needed. + vix = IntVector + .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) + .add(offset); + } else { + vix = IntVector + .fromArray(isp, indexMap, mapOffset) + .add(offset); + } + +#else[longOrDouble] + // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] + IntVector vix = IntVector + .fromArray(isp, indexMap, mapOffset) + .add(offset); +#end[longOrDouble] + + vix = VectorIntrinsics.checkIndex(vix, a.length); + + VectorSupport.storeWithMap( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + isp.vectorType(), + a, arrayAddress(a, 0), vix, + this, + a, offset, indexMap, mapOffset, + (arr, off, v, map, mo) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> { + int j = map[mo + i]; + arr[off + j] = e; + })); + } +#end[byteOrShort] + + /** + * Scatters this vector into an array of type {@code $type$[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then + * the lane element at index {@code N} is stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see $abstractvectortype$#toIntArray() + */ +#if[byteOrShort] + @ForceInline + public final + void intoArray($type$[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + stOp(a, offset, m, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = e; + }); + } +#else[byteOrShort] + @ForceInline + public final + void intoArray($type$[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + if (m.allTrue()) { + intoArray(a, offset, indexMap, mapOffset); + } + else { + // FIXME: Cannot vectorize yet, if there's a mask. + stOp(a, offset, m, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = e; + }); + } + } +#end[byteOrShort] + +#if[short] + /** + * Stores this vector into an array of type {@code char[]} + * starting at an offset. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array element {@code a[offset+N]}. + * + * @param a the array, of type {@code char[]} + * @param offset the offset into the array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset) { + offset = checkFromIndexSize(offset, length(), a.length); + $Type$Species vsp = vspecies(); + VectorSupport.store( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, charArrayAddress(a, offset), + this, + a, offset, + (arr, off, v) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> arr_[off_ + i] = (char) e)); + } + + /** + * Stores this vector into an array of type {@code char[]} + * starting at offset and using a mask. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array element {@code a[offset+N]}. + * If the mask lane at {@code N} is unset then the corresponding + * array element {@code a[offset+N]} is left unchanged. + *

+ * Array range checking is done for lanes where the mask is set. + * Lanes where the mask is unset are not stored and do not need + * to correspond to legitimate elements of {@code a}. + * That is, unset lanes may correspond to array indexes less than + * zero or beyond the end of the array. + * + * @param a the array, of type {@code char[]} + * @param offset the offset into the array + * @param m the mask controlling lane storage + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public final + void intoCharArray(char[] a, int offset, + VectorMask<$Boxtype$> m) { + if (m.allTrue()) { + intoCharArray(a, offset); + } else { + // FIXME: optimize + $Type$Species vsp = vspecies(); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = (char) v); + } + } + + /** + * Scatters this vector into an array of type {@code char[]} + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets * @param indexMap the index map * @param mapOffset the offset into the index map * @throws IndexOutOfBoundsException @@ -3576,74 +4108,186 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { * for any lane {@code N} in the vector * @see $abstractvectortype$#toIntArray() */ -#if[byteOrShort] @ForceInline public final - void intoArray($type$[] a, int offset, - int[] indexMap, int mapOffset) { + void intoCharArray(char[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize stOp(a, offset, (arr, off, i, e) -> { int j = indexMap[mapOffset + i]; - arr[off + j] = e; + arr[off + j] = (char) e; }); } -#else[byteOrShort] + + /** + * Scatters this vector into an array of type {@code char[]}, + * under the control of a mask, and + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * if the mask lane at index {@code N} is set then + * the lane element at index {@code N} + * is first cast to a {@code char} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @param m the mask + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * where the mask is set + * @see $abstractvectortype$#toIntArray() + */ @ForceInline public final - void intoArray($type$[] a, int offset, - int[] indexMap, int mapOffset) { + void intoCharArray(char[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + // FIXME: optimize + stOp(a, offset, m, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (char) e; + }); + } +#end[short] + +#if[byte] + /** + * Stores this vector into an array of type {@code boolean[]} + * starting at an offset. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array element {@code a[offset+N]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + * + * @param a the array + * @param offset the offset into the array + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset) { + offset = checkFromIndexSize(offset, length(), a.length); $Type$Species vsp = vspecies(); - IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); -#if[longOrDouble] - if (vsp.laneCount() == 1) { - intoArray(a, offset + indexMap[mapOffset]); - return; - } + ByteVector normalized = this.and((byte) 1); + VectorSupport.store( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, booleanArrayAddress(a, offset), + normalized, + a, offset, + (arr, off, v) + -> v.stOp(arr, off, + (arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0)); + } - // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] - IntVector vix; - if (isp.laneCount() != vsp.laneCount()) { - // For $Type$MaxVector, if vector length is 2048 bits, indexShape - // of $Type$ species is S_MAX_BIT. and the lane count of $Type$ - // vector is 32. When converting $Type$ species to int species, - // indexShape is still S_MAX_BIT, but the lane count of int vector - // is 64. So when loading index vector (IntVector), only lower half - // of index data is needed. - vix = IntVector - .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) - .add(offset); + /** + * Stores this vector into an array of type {@code boolean[]} + * starting at offset and using a mask. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array element {@code a[offset+N]}. + * If the mask lane at {@code N} is unset then the corresponding + * array element {@code a[offset+N]} is left unchanged. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + *

+ * Array range checking is done for lanes where the mask is set. + * Lanes where the mask is unset are not stored and do not need + * to correspond to legitimate elements of {@code a}. + * That is, unset lanes may correspond to array indexes less than + * zero or beyond the end of the array. + * + * @param a the array + * @param offset the offset into the array + * @param m the mask controlling lane storage + * @throws IndexOutOfBoundsException + * if {@code offset+N < 0} or {@code offset+N >= a.length} + * for any lane {@code N} in the vector + * where the mask is set + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset, + VectorMask<$Boxtype$> m) { + if (m.allTrue()) { + intoBooleanArray(a, offset); } else { - vix = IntVector - .fromArray(isp, indexMap, mapOffset) - .add(offset); + // FIXME: optimize + $Type$Species vsp = vspecies(); + checkMaskFromIndexSize(offset, vsp, m, 1, a.length); + stOp(a, offset, m, (arr, off, i, e) -> arr[off+i] = (e & 1) != 0); } + } -#else[longOrDouble] - // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] - IntVector vix = IntVector - .fromArray(isp, indexMap, mapOffset) - .add(offset); -#end[longOrDouble] - - vix = VectorIntrinsics.checkIndex(vix, a.length); - - VectorSupport.storeWithMap( - vsp.vectorType(), vsp.elementType(), vsp.laneCount(), - isp.vectorType(), - a, arrayAddress(a, 0), vix, - this, - a, offset, indexMap, mapOffset, - (arr, off, v, map, mo) - -> v.stOp(arr, off, - (arr_, off_, i, e) -> { - int j = map[mo + i]; - arr[off + j] = e; - })); + /** + * Scatters this vector into an array of type {@code boolean[]} + * using indexes obtained by adding a fixed {@code offset} to a + * series of secondary offsets from an index map. + * The index map is a contiguous sequence of {@code VLENGTH} + * elements in a second array of {@code int}s, starting at a given + * {@code mapOffset}. + *

+ * For each vector lane, where {@code N} is the vector lane index, + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array + * element {@code a[f(N)]}, where {@code f(N)} is the + * index mapping expression + * {@code offset + indexMap[mapOffset + N]]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. + * + * @param a the array + * @param offset an offset to combine with the index map offsets + * @param indexMap the index map + * @param mapOffset the offset into the index map + * @throws IndexOutOfBoundsException + * if {@code mapOffset+N < 0} + * or if {@code mapOffset+N >= indexMap.length}, + * or if {@code f(N)=offset+indexMap[mapOffset+N]} + * is an invalid index into {@code a}, + * for any lane {@code N} in the vector + * @see $abstractvectortype$#toIntArray() + */ + @ForceInline + public final + void intoBooleanArray(boolean[] a, int offset, + int[] indexMap, int mapOffset) { + // FIXME: optimize + stOp(a, offset, + (arr, off, i, e) -> { + int j = indexMap[mapOffset + i]; + arr[off + j] = (e & 1) != 0; + }); } -#end[byteOrShort] /** - * Scatters this vector into an array of type {@code $type$[]}, + * Scatters this vector into an array of type {@code boolean[]}, * under the control of a mask, and * using indexes obtained by adding a fixed {@code offset} to a * series of secondary offsets from an index map. @@ -3653,10 +4297,15 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { *

* For each vector lane, where {@code N} is the vector lane index, * if the mask lane at index {@code N} is set then - * the lane element at index {@code N} is stored into the array + * the lane element at index {@code N} + * is first converted to a {@code boolean} value and then + * stored into the array * element {@code a[f(N)]}, where {@code f(N)} is the * index mapping expression * {@code offset + indexMap[mapOffset + N]]}. + *

+ * A {@code byte} value is converted to a {@code boolean} value by applying the + * expression {@code (b & 1) != 0} where {@code b} is the byte value. * * @param a the array * @param offset an offset to combine with the index map offsets @@ -3672,37 +4321,19 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { * where the mask is set * @see $abstractvectortype$#toIntArray() */ -#if[byteOrShort] @ForceInline public final - void intoArray($type$[] a, int offset, - int[] indexMap, int mapOffset, - VectorMask<$Boxtype$> m) { + void intoBooleanArray(boolean[] a, int offset, + int[] indexMap, int mapOffset, + VectorMask<$Boxtype$> m) { + // FIXME: optimize stOp(a, offset, m, (arr, off, i, e) -> { int j = indexMap[mapOffset + i]; - arr[off + j] = e; + arr[off + j] = (e & 1) != 0; }); } -#else[byteOrShort] - @ForceInline - public final - void intoArray($type$[] a, int offset, - int[] indexMap, int mapOffset, - VectorMask<$Boxtype$> m) { - if (m.allTrue()) { - intoArray(a, offset, indexMap, mapOffset); - } - else { - // FIXME: Cannot vectorize yet, if there's a mask. - stOp(a, offset, m, - (arr, off, i, e) -> { - int j = indexMap[mapOffset + i]; - arr[off + j] = e; - }); - } - } -#end[byteOrShort] +#end[byte] /** * {@inheritDoc} @@ -3810,6 +4441,40 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { (arr_, off_, i) -> arr_[off_ + i])); } +#if[short] + /*package-private*/ + abstract + $abstractvectortype$ fromCharArray0(char[] a, int offset); + @ForceInline + final + $abstractvectortype$ fromCharArray0Template(char[] a, int offset) { + $Type$Species vsp = vspecies(); + return VectorSupport.load( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, charArrayAddress(a, offset), + a, offset, vsp, + (arr, off, s) -> s.ldOp(arr, off, + (arr_, off_, i) -> (short) arr_[off_ + i])); + } +#end[short] + +#if[byte] + /*package-private*/ + abstract + $abstractvectortype$ fromBooleanArray0(boolean[] a, int offset); + @ForceInline + final + $abstractvectortype$ fromBooleanArray0Template(boolean[] a, int offset) { + $Type$Species vsp = vspecies(); + return VectorSupport.load( + vsp.vectorType(), vsp.elementType(), vsp.laneCount(), + a, booleanArrayAddress(a, offset), + a, offset, vsp, + (arr, off, s) -> s.ldOp(arr, off, + (arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0))); + } +#end[byte] + @Override abstract $abstractvectortype$ fromByteArray0(byte[] a, int offset); @@ -3947,6 +4612,30 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); } +#if[short] + static final int ARRAY_CHAR_SHIFT = + 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_CHAR_INDEX_SCALE); + static final long ARRAY_CHAR_BASE = + Unsafe.ARRAY_CHAR_BASE_OFFSET; + + @ForceInline + static long charArrayAddress(char[] a, int index) { + return ARRAY_CHAR_BASE + (((long)index) << ARRAY_CHAR_SHIFT); + } +#end[short] + +#if[byte] + static final int ARRAY_BOOLEAN_SHIFT = + 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE); + static final long ARRAY_BOOLEAN_BASE = + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; + + @ForceInline + static long booleanArrayAddress(boolean[] a, int index) { + return ARRAY_BOOLEAN_BASE + (((long)index) << ARRAY_BOOLEAN_SHIFT); + } +#end[byte] + @ForceInline static long byteArrayAddress(byte[] a, int index) { return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template index aa3f4c926df..dcc681c5491 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template @@ -1099,6 +1099,24 @@ final class $vectortype$ extends $abstractvectortype$ { return super.fromArray0Template(a, offset); // specialize } +#if[short] + @ForceInline + @Override + final + $abstractvectortype$ fromCharArray0(char[] a, int offset) { + return super.fromCharArray0Template(a, offset); // specialize + } +#end[short] + +#if[byte] + @ForceInline + @Override + final + $abstractvectortype$ fromBooleanArray0(boolean[] a, int offset) { + return super.fromBooleanArray0Template(a, offset); // specialize + } +#end[byte] + @ForceInline @Override final diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorLoadStoreTests.java index f29b70e55cb..0c2cd0264a9 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorLoadStoreTests.java @@ -948,4 +948,94 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } } diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java index a3861e75f3c..bddd2663eaa 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java @@ -980,8 +980,9 @@ public Object[][] byteUnaryOpShuffleMaskProvider() { static final List> BYTE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { byte[] a = new byte[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (byte)RAND.nextInt(m); + a[i] = (byte)RAND.nextInt(upper); } return a; }) @@ -1042,6 +1043,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (byte)i); }), + withToString("byte[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(i - (s * BUFFER_REPS / 2))); + }), withToString("byte[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (byte)(i + 1)); @@ -1165,6 +1170,46 @@ static void replaceZero(byte[] a, boolean[] mask, byte v) { } } + static boolean eq(byte a, byte b) { + return a == b; + } + + static boolean neq(byte a, byte b) { + return a != b; + } + + static boolean lt(byte a, byte b) { + return a < b; + } + + static boolean le(byte a, byte b) { + return a <= b; + } + + static boolean gt(byte a, byte b) { + return a > b; + } + + static boolean ge(byte a, byte b) { + return a >= b; + } + + static boolean ult(byte a, byte b) { + return Byte.compareUnsigned(a, b) < 0; + } + + static boolean ule(byte a, byte b) { + return Byte.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(byte a, byte b) { + return Byte.compareUnsigned(a, b) > 0; + } + + static boolean uge(byte a, byte b) { + return Byte.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3337,7 +3382,7 @@ static void LTByte128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3357,7 +3402,7 @@ static void ltByte128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3380,7 +3425,7 @@ static void LTByte128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3423,7 +3468,7 @@ static void GTByte128VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3443,7 +3488,7 @@ static void EQByte128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3463,7 +3508,7 @@ static void eqByte128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3486,7 +3531,7 @@ static void EQByte128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3529,7 +3574,7 @@ static void NEByte128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3572,7 +3617,7 @@ static void LEByte128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3615,13 +3660,201 @@ static void GEByte128VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LTByte128VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LTByte128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GTByte128VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GTByte128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LEByte128VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LEByte128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GEByte128VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GEByte128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "byteCompareOpProvider") static void LTByte128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { byte[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorLoadStoreTests.java index 91e4b492242..38cabb5868b 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorLoadStoreTests.java @@ -948,4 +948,94 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } } diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java index 1d80c929cd9..0b96fc50f90 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java @@ -980,8 +980,9 @@ public Object[][] byteUnaryOpShuffleMaskProvider() { static final List> BYTE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { byte[] a = new byte[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (byte)RAND.nextInt(m); + a[i] = (byte)RAND.nextInt(upper); } return a; }) @@ -1042,6 +1043,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (byte)i); }), + withToString("byte[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(i - (s * BUFFER_REPS / 2))); + }), withToString("byte[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (byte)(i + 1)); @@ -1165,6 +1170,46 @@ static void replaceZero(byte[] a, boolean[] mask, byte v) { } } + static boolean eq(byte a, byte b) { + return a == b; + } + + static boolean neq(byte a, byte b) { + return a != b; + } + + static boolean lt(byte a, byte b) { + return a < b; + } + + static boolean le(byte a, byte b) { + return a <= b; + } + + static boolean gt(byte a, byte b) { + return a > b; + } + + static boolean ge(byte a, byte b) { + return a >= b; + } + + static boolean ult(byte a, byte b) { + return Byte.compareUnsigned(a, b) < 0; + } + + static boolean ule(byte a, byte b) { + return Byte.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(byte a, byte b) { + return Byte.compareUnsigned(a, b) > 0; + } + + static boolean uge(byte a, byte b) { + return Byte.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3337,7 +3382,7 @@ static void LTByte256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3357,7 +3402,7 @@ static void ltByte256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3380,7 +3425,7 @@ static void LTByte256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3423,7 +3468,7 @@ static void GTByte256VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3443,7 +3488,7 @@ static void EQByte256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3463,7 +3508,7 @@ static void eqByte256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3486,7 +3531,7 @@ static void EQByte256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3529,7 +3574,7 @@ static void NEByte256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3572,7 +3617,7 @@ static void LEByte256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3615,13 +3660,201 @@ static void GEByte256VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LTByte256VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LTByte256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GTByte256VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GTByte256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LEByte256VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LEByte256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GEByte256VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GEByte256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "byteCompareOpProvider") static void LTByte256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { byte[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorLoadStoreTests.java index e943dab00d5..9fc2d6a031e 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorLoadStoreTests.java @@ -948,4 +948,94 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } } diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java index d0371c79cf9..a47b67ba616 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java @@ -980,8 +980,9 @@ public Object[][] byteUnaryOpShuffleMaskProvider() { static final List> BYTE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { byte[] a = new byte[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (byte)RAND.nextInt(m); + a[i] = (byte)RAND.nextInt(upper); } return a; }) @@ -1042,6 +1043,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (byte)i); }), + withToString("byte[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(i - (s * BUFFER_REPS / 2))); + }), withToString("byte[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (byte)(i + 1)); @@ -1165,6 +1170,46 @@ static void replaceZero(byte[] a, boolean[] mask, byte v) { } } + static boolean eq(byte a, byte b) { + return a == b; + } + + static boolean neq(byte a, byte b) { + return a != b; + } + + static boolean lt(byte a, byte b) { + return a < b; + } + + static boolean le(byte a, byte b) { + return a <= b; + } + + static boolean gt(byte a, byte b) { + return a > b; + } + + static boolean ge(byte a, byte b) { + return a >= b; + } + + static boolean ult(byte a, byte b) { + return Byte.compareUnsigned(a, b) < 0; + } + + static boolean ule(byte a, byte b) { + return Byte.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(byte a, byte b) { + return Byte.compareUnsigned(a, b) > 0; + } + + static boolean uge(byte a, byte b) { + return Byte.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3337,7 +3382,7 @@ static void LTByte512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3357,7 +3402,7 @@ static void ltByte512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3380,7 +3425,7 @@ static void LTByte512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3423,7 +3468,7 @@ static void GTByte512VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3443,7 +3488,7 @@ static void EQByte512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3463,7 +3508,7 @@ static void eqByte512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3486,7 +3531,7 @@ static void EQByte512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3529,7 +3574,7 @@ static void NEByte512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3572,7 +3617,7 @@ static void LEByte512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3615,13 +3660,201 @@ static void GEByte512VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LTByte512VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LTByte512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GTByte512VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GTByte512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LEByte512VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LEByte512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GEByte512VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GEByte512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "byteCompareOpProvider") static void LTByte512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { byte[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorLoadStoreTests.java index 898f554b6ef..49c9097b3ef 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorLoadStoreTests.java @@ -948,4 +948,94 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } } diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java index 5f810647bbe..c5db8ab1b06 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java @@ -980,8 +980,9 @@ public Object[][] byteUnaryOpShuffleMaskProvider() { static final List> BYTE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { byte[] a = new byte[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (byte)RAND.nextInt(m); + a[i] = (byte)RAND.nextInt(upper); } return a; }) @@ -1042,6 +1043,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (byte)i); }), + withToString("byte[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(i - (s * BUFFER_REPS / 2))); + }), withToString("byte[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (byte)(i + 1)); @@ -1165,6 +1170,46 @@ static void replaceZero(byte[] a, boolean[] mask, byte v) { } } + static boolean eq(byte a, byte b) { + return a == b; + } + + static boolean neq(byte a, byte b) { + return a != b; + } + + static boolean lt(byte a, byte b) { + return a < b; + } + + static boolean le(byte a, byte b) { + return a <= b; + } + + static boolean gt(byte a, byte b) { + return a > b; + } + + static boolean ge(byte a, byte b) { + return a >= b; + } + + static boolean ult(byte a, byte b) { + return Byte.compareUnsigned(a, b) < 0; + } + + static boolean ule(byte a, byte b) { + return Byte.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(byte a, byte b) { + return Byte.compareUnsigned(a, b) > 0; + } + + static boolean uge(byte a, byte b) { + return Byte.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3337,7 +3382,7 @@ static void LTByte64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3357,7 +3402,7 @@ static void ltByte64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3380,7 +3425,7 @@ static void LTByte64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3423,7 +3468,7 @@ static void GTByte64VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3443,7 +3488,7 @@ static void EQByte64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3463,7 +3508,7 @@ static void eqByte64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3486,7 +3531,7 @@ static void EQByte64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3529,7 +3574,7 @@ static void NEByte64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3572,7 +3617,7 @@ static void LEByte64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3615,13 +3660,201 @@ static void GEByte64VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LTByte64VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LTByte64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GTByte64VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GTByte64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LEByte64VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LEByte64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GEByte64VectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GEByte64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "byteCompareOpProvider") static void LTByte64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { byte[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorLoadStoreTests.java index 6c73a4d1654..31fe42ca1cc 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorLoadStoreTests.java @@ -957,4 +957,94 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } } diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java index 72005730caa..8e4fca80857 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java @@ -985,8 +985,9 @@ public Object[][] byteUnaryOpShuffleMaskProvider() { static final List> BYTE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { byte[] a = new byte[l]; + int upper = Math.min(Byte.MAX_VALUE + 1, m); for (int i = 0; i < 1; i++) { - a[i] = (byte)RAND.nextInt(m); + a[i] = (byte)RAND.nextInt(upper); } return a; }) @@ -1047,6 +1048,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (byte)i); }), + withToString("byte[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(i - (s * BUFFER_REPS / 2))); + }), withToString("byte[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (byte)(i + 1)); @@ -1170,6 +1175,46 @@ static void replaceZero(byte[] a, boolean[] mask, byte v) { } } + static boolean eq(byte a, byte b) { + return a == b; + } + + static boolean neq(byte a, byte b) { + return a != b; + } + + static boolean lt(byte a, byte b) { + return a < b; + } + + static boolean le(byte a, byte b) { + return a <= b; + } + + static boolean gt(byte a, byte b) { + return a > b; + } + + static boolean ge(byte a, byte b) { + return a >= b; + } + + static boolean ult(byte a, byte b) { + return Byte.compareUnsigned(a, b) < 0; + } + + static boolean ule(byte a, byte b) { + return Byte.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(byte a, byte b) { + return Byte.compareUnsigned(a, b) > 0; + } + + static boolean uge(byte a, byte b) { + return Byte.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3342,7 +3387,7 @@ static void LTByteMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3362,7 +3407,7 @@ static void ltByteMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3385,7 +3430,7 @@ static void LTByteMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3428,7 +3473,7 @@ static void GTByteMaxVectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3448,7 +3493,7 @@ static void EQByteMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3468,7 +3513,7 @@ static void eqByteMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3491,7 +3536,7 @@ static void EQByteMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3534,7 +3579,7 @@ static void NEByteMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3577,7 +3622,7 @@ static void LEByteMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3620,13 +3665,201 @@ static void GEByteMaxVectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LTByteMaxVectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LTByteMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GTByteMaxVectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GTByteMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_LEByteMaxVectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_LEByteMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "byteCompareOpProvider") + static void UNSIGNED_GEByteMaxVectorTests(IntFunction fa, IntFunction fb) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "byteCompareOpMaskProvider") + static void UNSIGNED_GEByteMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "byteCompareOpProvider") static void LTByteMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { byte[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Double128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Double128VectorLoadStoreTests.java index ce83d46978b..c1d926000ad 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java index 11ec69a87c8..880b9bab374 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java @@ -1112,8 +1112,9 @@ public Object[][] doubleUnaryOpShuffleMaskProvider() { static final List> DOUBLE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { double[] a = new double[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (double)RAND.nextInt(m); + a[i] = (double)RAND.nextInt(upper); } return a; }) @@ -1174,6 +1175,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (double)i); }), + withToString("double[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(i - (s * BUFFER_REPS / 2))); + }), withToString("double[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (double)(i + 1)); @@ -1286,6 +1291,31 @@ static double get(double[] a, int i) { }; + static boolean eq(double a, double b) { + return a == b; + } + + static boolean neq(double a, double b) { + return a != b; + } + + static boolean lt(double a, double b) { + return a < b; + } + + static boolean le(double a, double b) { + return a <= b; + } + + static boolean gt(double a, double b) { + return a > b; + } + + static boolean ge(double a, double b) { + return a >= b; + } + + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2654,7 +2684,7 @@ static void LTDouble128VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2740,7 +2770,7 @@ static void GTDouble128VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2760,7 +2790,7 @@ static void EQDouble128VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2932,13 +2962,21 @@ static void GEDouble128VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "doubleCompareOpProvider") static void LTDouble128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { double[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Double256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Double256VectorLoadStoreTests.java index 774033e3f94..82516e40e60 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java index 3d30815992b..7919a57e4c2 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java @@ -1112,8 +1112,9 @@ public Object[][] doubleUnaryOpShuffleMaskProvider() { static final List> DOUBLE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { double[] a = new double[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (double)RAND.nextInt(m); + a[i] = (double)RAND.nextInt(upper); } return a; }) @@ -1174,6 +1175,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (double)i); }), + withToString("double[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(i - (s * BUFFER_REPS / 2))); + }), withToString("double[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (double)(i + 1)); @@ -1286,6 +1291,31 @@ static double get(double[] a, int i) { }; + static boolean eq(double a, double b) { + return a == b; + } + + static boolean neq(double a, double b) { + return a != b; + } + + static boolean lt(double a, double b) { + return a < b; + } + + static boolean le(double a, double b) { + return a <= b; + } + + static boolean gt(double a, double b) { + return a > b; + } + + static boolean ge(double a, double b) { + return a >= b; + } + + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2654,7 +2684,7 @@ static void LTDouble256VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2740,7 +2770,7 @@ static void GTDouble256VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2760,7 +2790,7 @@ static void EQDouble256VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2932,13 +2962,21 @@ static void GEDouble256VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "doubleCompareOpProvider") static void LTDouble256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { double[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Double512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Double512VectorLoadStoreTests.java index 1769ad02752..40abdc58fb4 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java index 488898f9bce..e53714ce294 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java @@ -1112,8 +1112,9 @@ public Object[][] doubleUnaryOpShuffleMaskProvider() { static final List> DOUBLE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { double[] a = new double[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (double)RAND.nextInt(m); + a[i] = (double)RAND.nextInt(upper); } return a; }) @@ -1174,6 +1175,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (double)i); }), + withToString("double[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(i - (s * BUFFER_REPS / 2))); + }), withToString("double[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (double)(i + 1)); @@ -1286,6 +1291,31 @@ static double get(double[] a, int i) { }; + static boolean eq(double a, double b) { + return a == b; + } + + static boolean neq(double a, double b) { + return a != b; + } + + static boolean lt(double a, double b) { + return a < b; + } + + static boolean le(double a, double b) { + return a <= b; + } + + static boolean gt(double a, double b) { + return a > b; + } + + static boolean ge(double a, double b) { + return a >= b; + } + + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2654,7 +2684,7 @@ static void LTDouble512VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2740,7 +2770,7 @@ static void GTDouble512VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2760,7 +2790,7 @@ static void EQDouble512VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2932,13 +2962,21 @@ static void GEDouble512VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "doubleCompareOpProvider") static void LTDouble512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { double[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Double64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Double64VectorLoadStoreTests.java index 1432f079aa5..b70a469e6e0 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java index 2c648659a54..37c43a119ba 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java @@ -1112,8 +1112,9 @@ public Object[][] doubleUnaryOpShuffleMaskProvider() { static final List> DOUBLE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { double[] a = new double[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (double)RAND.nextInt(m); + a[i] = (double)RAND.nextInt(upper); } return a; }) @@ -1174,6 +1175,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (double)i); }), + withToString("double[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(i - (s * BUFFER_REPS / 2))); + }), withToString("double[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (double)(i + 1)); @@ -1286,6 +1291,31 @@ static double get(double[] a, int i) { }; + static boolean eq(double a, double b) { + return a == b; + } + + static boolean neq(double a, double b) { + return a != b; + } + + static boolean lt(double a, double b) { + return a < b; + } + + static boolean le(double a, double b) { + return a <= b; + } + + static boolean gt(double a, double b) { + return a > b; + } + + static boolean ge(double a, double b) { + return a >= b; + } + + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2654,7 +2684,7 @@ static void LTDouble64VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2740,7 +2770,7 @@ static void GTDouble64VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2760,7 +2790,7 @@ static void EQDouble64VectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2932,13 +2962,21 @@ static void GEDouble64VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "doubleCompareOpProvider") static void LTDouble64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { double[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorLoadStoreTests.java index 5fbea075223..2bfb16ed30a 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorLoadStoreTests.java @@ -968,4 +968,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java index f5a736e1d49..09189a2b103 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java @@ -1117,8 +1117,9 @@ public Object[][] doubleUnaryOpShuffleMaskProvider() { static final List> DOUBLE_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { double[] a = new double[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (double)RAND.nextInt(m); + a[i] = (double)RAND.nextInt(upper); } return a; }) @@ -1179,6 +1180,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (double)i); }), + withToString("double[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(i - (s * BUFFER_REPS / 2))); + }), withToString("double[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (double)(i + 1)); @@ -1291,6 +1296,31 @@ static double get(double[] a, int i) { }; + static boolean eq(double a, double b) { + return a == b; + } + + static boolean neq(double a, double b) { + return a != b; + } + + static boolean lt(double a, double b) { + return a < b; + } + + static boolean le(double a, double b) { + return a <= b; + } + + static boolean gt(double a, double b) { + return a > b; + } + + static boolean ge(double a, double b) { + return a >= b; + } + + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2659,7 +2689,7 @@ static void LTDoubleMaxVectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2745,7 +2775,7 @@ static void GTDoubleMaxVectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2765,7 +2795,7 @@ static void EQDoubleMaxVectorTests(IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction fa, IntFunction= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2937,13 +2967,21 @@ static void GEDoubleMaxVectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "doubleCompareOpProvider") static void LTDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { double[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Float128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Float128VectorLoadStoreTests.java index f0136f574a5..85a3a3929c8 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java index da2cddbcdec..30ebec15bea 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java @@ -1122,8 +1122,9 @@ public Object[][] floatUnaryOpShuffleMaskProvider() { static final List> FLOAT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { float[] a = new float[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (float)RAND.nextInt(m); + a[i] = (float)RAND.nextInt(upper); } return a; }) @@ -1184,6 +1185,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (float)i); }), + withToString("float[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(i - (s * BUFFER_REPS / 2))); + }), withToString("float[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (float)(i + 1)); @@ -1296,6 +1301,31 @@ static float get(float[] a, int i) { }; + static boolean eq(float a, float b) { + return a == b; + } + + static boolean neq(float a, float b) { + return a != b; + } + + static boolean lt(float a, float b) { + return a < b; + } + + static boolean le(float a, float b) { + return a <= b; + } + + static boolean gt(float a, float b) { + return a > b; + } + + static boolean ge(float a, float b) { + return a >= b; + } + + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2664,7 +2694,7 @@ static void LTFloat128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2684,7 +2714,7 @@ static void ltFloat128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2707,7 +2737,7 @@ static void LTFloat128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2750,7 +2780,7 @@ static void GTFloat128VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2770,7 +2800,7 @@ static void EQFloat128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2790,7 +2820,7 @@ static void eqFloat128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2813,7 +2843,7 @@ static void EQFloat128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -2856,7 +2886,7 @@ static void NEFloat128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -2899,7 +2929,7 @@ static void LEFloat128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2942,13 +2972,21 @@ static void GEFloat128VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "floatCompareOpProvider") static void LTFloat128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { float[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Float256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Float256VectorLoadStoreTests.java index f5e138ecd4e..9c965056576 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java index 3e5be0ecd5a..2f4beda5c93 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java @@ -1122,8 +1122,9 @@ public Object[][] floatUnaryOpShuffleMaskProvider() { static final List> FLOAT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { float[] a = new float[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (float)RAND.nextInt(m); + a[i] = (float)RAND.nextInt(upper); } return a; }) @@ -1184,6 +1185,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (float)i); }), + withToString("float[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(i - (s * BUFFER_REPS / 2))); + }), withToString("float[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (float)(i + 1)); @@ -1296,6 +1301,31 @@ static float get(float[] a, int i) { }; + static boolean eq(float a, float b) { + return a == b; + } + + static boolean neq(float a, float b) { + return a != b; + } + + static boolean lt(float a, float b) { + return a < b; + } + + static boolean le(float a, float b) { + return a <= b; + } + + static boolean gt(float a, float b) { + return a > b; + } + + static boolean ge(float a, float b) { + return a >= b; + } + + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2664,7 +2694,7 @@ static void LTFloat256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2684,7 +2714,7 @@ static void ltFloat256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2707,7 +2737,7 @@ static void LTFloat256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2750,7 +2780,7 @@ static void GTFloat256VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2770,7 +2800,7 @@ static void EQFloat256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2790,7 +2820,7 @@ static void eqFloat256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2813,7 +2843,7 @@ static void EQFloat256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -2856,7 +2886,7 @@ static void NEFloat256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -2899,7 +2929,7 @@ static void LEFloat256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2942,13 +2972,21 @@ static void GEFloat256VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "floatCompareOpProvider") static void LTFloat256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { float[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Float512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Float512VectorLoadStoreTests.java index 967e44c0d03..260d718d406 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java index 2d9eebf3de0..3f2fbf8455d 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java @@ -1122,8 +1122,9 @@ public Object[][] floatUnaryOpShuffleMaskProvider() { static final List> FLOAT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { float[] a = new float[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (float)RAND.nextInt(m); + a[i] = (float)RAND.nextInt(upper); } return a; }) @@ -1184,6 +1185,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (float)i); }), + withToString("float[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(i - (s * BUFFER_REPS / 2))); + }), withToString("float[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (float)(i + 1)); @@ -1296,6 +1301,31 @@ static float get(float[] a, int i) { }; + static boolean eq(float a, float b) { + return a == b; + } + + static boolean neq(float a, float b) { + return a != b; + } + + static boolean lt(float a, float b) { + return a < b; + } + + static boolean le(float a, float b) { + return a <= b; + } + + static boolean gt(float a, float b) { + return a > b; + } + + static boolean ge(float a, float b) { + return a >= b; + } + + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2664,7 +2694,7 @@ static void LTFloat512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2684,7 +2714,7 @@ static void ltFloat512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2707,7 +2737,7 @@ static void LTFloat512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2750,7 +2780,7 @@ static void GTFloat512VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2770,7 +2800,7 @@ static void EQFloat512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2790,7 +2820,7 @@ static void eqFloat512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2813,7 +2843,7 @@ static void EQFloat512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -2856,7 +2886,7 @@ static void NEFloat512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -2899,7 +2929,7 @@ static void LEFloat512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2942,13 +2972,21 @@ static void GEFloat512VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "floatCompareOpProvider") static void LTFloat512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { float[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Float64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Float64VectorLoadStoreTests.java index 82286b4e295..3d92c17d4fd 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java index 8e567f57891..3e30005710f 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java @@ -1122,8 +1122,9 @@ public Object[][] floatUnaryOpShuffleMaskProvider() { static final List> FLOAT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { float[] a = new float[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (float)RAND.nextInt(m); + a[i] = (float)RAND.nextInt(upper); } return a; }) @@ -1184,6 +1185,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (float)i); }), + withToString("float[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(i - (s * BUFFER_REPS / 2))); + }), withToString("float[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (float)(i + 1)); @@ -1296,6 +1301,31 @@ static float get(float[] a, int i) { }; + static boolean eq(float a, float b) { + return a == b; + } + + static boolean neq(float a, float b) { + return a != b; + } + + static boolean lt(float a, float b) { + return a < b; + } + + static boolean le(float a, float b) { + return a <= b; + } + + static boolean gt(float a, float b) { + return a > b; + } + + static boolean ge(float a, float b) { + return a >= b; + } + + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2664,7 +2694,7 @@ static void LTFloat64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2684,7 +2714,7 @@ static void ltFloat64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2707,7 +2737,7 @@ static void LTFloat64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2750,7 +2780,7 @@ static void GTFloat64VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2770,7 +2800,7 @@ static void EQFloat64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2790,7 +2820,7 @@ static void eqFloat64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2813,7 +2843,7 @@ static void EQFloat64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -2856,7 +2886,7 @@ static void NEFloat64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -2899,7 +2929,7 @@ static void LEFloat64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2942,13 +2972,21 @@ static void GEFloat64VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "floatCompareOpProvider") static void LTFloat64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { float[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorLoadStoreTests.java index f0a4ef7382c..fae205df970 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorLoadStoreTests.java @@ -968,4 +968,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java index 1997645ee80..1563496bac3 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java @@ -1127,8 +1127,9 @@ public Object[][] floatUnaryOpShuffleMaskProvider() { static final List> FLOAT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { float[] a = new float[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (float)RAND.nextInt(m); + a[i] = (float)RAND.nextInt(upper); } return a; }) @@ -1189,6 +1190,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (float)i); }), + withToString("float[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(i - (s * BUFFER_REPS / 2))); + }), withToString("float[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (float)(i + 1)); @@ -1301,6 +1306,31 @@ static float get(float[] a, int i) { }; + static boolean eq(float a, float b) { + return a == b; + } + + static boolean neq(float a, float b) { + return a != b; + } + + static boolean lt(float a, float b) { + return a < b; + } + + static boolean le(float a, float b) { + return a <= b; + } + + static boolean gt(float a, float b) { + return a > b; + } + + static boolean ge(float a, float b) { + return a >= b; + } + + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2669,7 +2699,7 @@ static void LTFloatMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2689,7 +2719,7 @@ static void ltFloatMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -2712,7 +2742,7 @@ static void LTFloatMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -2755,7 +2785,7 @@ static void GTFloatMaxVectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -2775,7 +2805,7 @@ static void EQFloatMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2795,7 +2825,7 @@ static void eqFloatMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -2818,7 +2848,7 @@ static void EQFloatMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -2861,7 +2891,7 @@ static void NEFloatMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -2904,7 +2934,7 @@ static void LEFloatMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -2947,13 +2977,21 @@ static void GEFloatMaxVectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); } } } } + + + + + + + + @Test(dataProvider = "floatCompareOpProvider") static void LTFloatMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { float[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Int128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Int128VectorLoadStoreTests.java index 88c93884dd7..392f3f2866f 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java index 9ad6a2b806b..2f6437c806d 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java @@ -1003,6 +1003,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (int)i); }), + withToString("int[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(i - (s * BUFFER_REPS / 2))); + }), withToString("int[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (int)(i + 1)); @@ -1126,6 +1130,46 @@ static void replaceZero(int[] a, boolean[] mask, int v) { } } + static boolean eq(int a, int b) { + return a == b; + } + + static boolean neq(int a, int b) { + return a != b; + } + + static boolean lt(int a, int b) { + return a < b; + } + + static boolean le(int a, int b) { + return a <= b; + } + + static boolean gt(int a, int b) { + return a > b; + } + + static boolean ge(int a, int b) { + return a >= b; + } + + static boolean ult(int a, int b) { + return Integer.compareUnsigned(a, b) < 0; + } + + static boolean ule(int a, int b) { + return Integer.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(int a, int b) { + return Integer.compareUnsigned(a, b) > 0; + } + + static boolean uge(int a, int b) { + return Integer.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3303,7 +3347,7 @@ static void LTInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3323,7 +3367,7 @@ static void ltInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3346,7 +3390,7 @@ static void LTInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j])); } } } @@ -3366,7 +3410,7 @@ static void GTInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3389,7 +3433,7 @@ static void GTInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] > b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3409,7 +3453,7 @@ static void EQInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3429,7 +3473,7 @@ static void eqInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3452,7 +3496,7 @@ static void EQInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j])); } } } @@ -3472,7 +3516,7 @@ static void NEInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3495,7 +3539,7 @@ static void NEInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] != b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j])); } } } @@ -3515,7 +3559,7 @@ static void LEInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3538,7 +3582,7 @@ static void LEInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] <= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j])); } } } @@ -3558,7 +3602,7 @@ static void GEInt128VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3581,13 +3625,201 @@ static void GEInt128VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] >= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LTInt128VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LTInt128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GTInt128VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GTInt128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LEInt128VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LEInt128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GEInt128VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GEInt128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "intCompareOpProvider") static void LTInt128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { int[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Int256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Int256VectorLoadStoreTests.java index b00e60b96fd..ae4b9534dd2 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java index d79d1ce49d9..45dad70dbf5 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java @@ -1003,6 +1003,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (int)i); }), + withToString("int[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(i - (s * BUFFER_REPS / 2))); + }), withToString("int[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (int)(i + 1)); @@ -1126,6 +1130,46 @@ static void replaceZero(int[] a, boolean[] mask, int v) { } } + static boolean eq(int a, int b) { + return a == b; + } + + static boolean neq(int a, int b) { + return a != b; + } + + static boolean lt(int a, int b) { + return a < b; + } + + static boolean le(int a, int b) { + return a <= b; + } + + static boolean gt(int a, int b) { + return a > b; + } + + static boolean ge(int a, int b) { + return a >= b; + } + + static boolean ult(int a, int b) { + return Integer.compareUnsigned(a, b) < 0; + } + + static boolean ule(int a, int b) { + return Integer.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(int a, int b) { + return Integer.compareUnsigned(a, b) > 0; + } + + static boolean uge(int a, int b) { + return Integer.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3303,7 +3347,7 @@ static void LTInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3323,7 +3367,7 @@ static void ltInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3346,7 +3390,7 @@ static void LTInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j])); } } } @@ -3366,7 +3410,7 @@ static void GTInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3389,7 +3433,7 @@ static void GTInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] > b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3409,7 +3453,7 @@ static void EQInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3429,7 +3473,7 @@ static void eqInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3452,7 +3496,7 @@ static void EQInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j])); } } } @@ -3472,7 +3516,7 @@ static void NEInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3495,7 +3539,7 @@ static void NEInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] != b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j])); } } } @@ -3515,7 +3559,7 @@ static void LEInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3538,7 +3582,7 @@ static void LEInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] <= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j])); } } } @@ -3558,7 +3602,7 @@ static void GEInt256VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3581,13 +3625,201 @@ static void GEInt256VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] >= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LTInt256VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LTInt256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GTInt256VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GTInt256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LEInt256VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LEInt256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GEInt256VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GEInt256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "intCompareOpProvider") static void LTInt256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { int[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Int512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Int512VectorLoadStoreTests.java index c7c5d1a0b50..1d700e232a5 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java index dd73991c6d0..66eab1a77d6 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java @@ -1003,6 +1003,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (int)i); }), + withToString("int[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(i - (s * BUFFER_REPS / 2))); + }), withToString("int[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (int)(i + 1)); @@ -1126,6 +1130,46 @@ static void replaceZero(int[] a, boolean[] mask, int v) { } } + static boolean eq(int a, int b) { + return a == b; + } + + static boolean neq(int a, int b) { + return a != b; + } + + static boolean lt(int a, int b) { + return a < b; + } + + static boolean le(int a, int b) { + return a <= b; + } + + static boolean gt(int a, int b) { + return a > b; + } + + static boolean ge(int a, int b) { + return a >= b; + } + + static boolean ult(int a, int b) { + return Integer.compareUnsigned(a, b) < 0; + } + + static boolean ule(int a, int b) { + return Integer.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(int a, int b) { + return Integer.compareUnsigned(a, b) > 0; + } + + static boolean uge(int a, int b) { + return Integer.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3303,7 +3347,7 @@ static void LTInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3323,7 +3367,7 @@ static void ltInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3346,7 +3390,7 @@ static void LTInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j])); } } } @@ -3366,7 +3410,7 @@ static void GTInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3389,7 +3433,7 @@ static void GTInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] > b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3409,7 +3453,7 @@ static void EQInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3429,7 +3473,7 @@ static void eqInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3452,7 +3496,7 @@ static void EQInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j])); } } } @@ -3472,7 +3516,7 @@ static void NEInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3495,7 +3539,7 @@ static void NEInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] != b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j])); } } } @@ -3515,7 +3559,7 @@ static void LEInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3538,7 +3582,7 @@ static void LEInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] <= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j])); } } } @@ -3558,7 +3602,7 @@ static void GEInt512VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3581,13 +3625,201 @@ static void GEInt512VectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] >= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LTInt512VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LTInt512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GTInt512VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GTInt512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LEInt512VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LEInt512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GEInt512VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GEInt512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "intCompareOpProvider") static void LTInt512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { int[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Int64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Int64VectorLoadStoreTests.java index 992d5fd35c7..f232dfdfa01 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java index 2bde75eeea0..43e796cdc18 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java @@ -1003,6 +1003,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (int)i); }), + withToString("int[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(i - (s * BUFFER_REPS / 2))); + }), withToString("int[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (int)(i + 1)); @@ -1126,6 +1130,46 @@ static void replaceZero(int[] a, boolean[] mask, int v) { } } + static boolean eq(int a, int b) { + return a == b; + } + + static boolean neq(int a, int b) { + return a != b; + } + + static boolean lt(int a, int b) { + return a < b; + } + + static boolean le(int a, int b) { + return a <= b; + } + + static boolean gt(int a, int b) { + return a > b; + } + + static boolean ge(int a, int b) { + return a >= b; + } + + static boolean ult(int a, int b) { + return Integer.compareUnsigned(a, b) < 0; + } + + static boolean ule(int a, int b) { + return Integer.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(int a, int b) { + return Integer.compareUnsigned(a, b) > 0; + } + + static boolean uge(int a, int b) { + return Integer.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3303,7 +3347,7 @@ static void LTInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3323,7 +3367,7 @@ static void ltInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3346,7 +3390,7 @@ static void LTInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j])); } } } @@ -3366,7 +3410,7 @@ static void GTInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3389,7 +3433,7 @@ static void GTInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] > b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3409,7 +3453,7 @@ static void EQInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3429,7 +3473,7 @@ static void eqInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3452,7 +3496,7 @@ static void EQInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j])); } } } @@ -3472,7 +3516,7 @@ static void NEInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3495,7 +3539,7 @@ static void NEInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] != b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j])); } } } @@ -3515,7 +3559,7 @@ static void LEInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3538,7 +3582,7 @@ static void LEInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] <= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j])); } } } @@ -3558,7 +3602,7 @@ static void GEInt64VectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3581,13 +3625,201 @@ static void GEInt64VectorTestsMasked(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] >= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LTInt64VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LTInt64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GTInt64VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GTInt64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LEInt64VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LEInt64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GEInt64VectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GEInt64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "intCompareOpProvider") static void LTInt64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { int[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorLoadStoreTests.java index 251bc4fe51b..65017307ef4 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorLoadStoreTests.java @@ -968,4 +968,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java index 54728ef130d..345bbda2db3 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java @@ -1008,6 +1008,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (int)i); }), + withToString("int[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(i - (s * BUFFER_REPS / 2))); + }), withToString("int[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (int)(i + 1)); @@ -1131,6 +1135,46 @@ static void replaceZero(int[] a, boolean[] mask, int v) { } } + static boolean eq(int a, int b) { + return a == b; + } + + static boolean neq(int a, int b) { + return a != b; + } + + static boolean lt(int a, int b) { + return a < b; + } + + static boolean le(int a, int b) { + return a <= b; + } + + static boolean gt(int a, int b) { + return a > b; + } + + static boolean ge(int a, int b) { + return a >= b; + } + + static boolean ult(int a, int b) { + return Integer.compareUnsigned(a, b) < 0; + } + + static boolean ule(int a, int b) { + return Integer.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(int a, int b) { + return Integer.compareUnsigned(a, b) > 0; + } + + static boolean uge(int a, int b) { + return Integer.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3308,7 +3352,7 @@ static void LTIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3328,7 +3372,7 @@ static void ltIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3351,7 +3395,7 @@ static void LTIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j])); } } } @@ -3371,7 +3415,7 @@ static void GTIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3394,7 +3438,7 @@ static void GTIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] > b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3414,7 +3458,7 @@ static void EQIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3434,7 +3478,7 @@ static void eqIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3457,7 +3501,7 @@ static void EQIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j])); } } } @@ -3477,7 +3521,7 @@ static void NEIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3500,7 +3544,7 @@ static void NEIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] != b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j])); } } } @@ -3520,7 +3564,7 @@ static void LEIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3543,7 +3587,7 @@ static void LEIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] <= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j])); } } } @@ -3563,7 +3607,7 @@ static void GEIntMaxVectorTests(IntFunction fa, IntFunction fb) { // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3586,13 +3630,201 @@ static void GEIntMaxVectorTestsMasked(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] >= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LTIntMaxVectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LTIntMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GTIntMaxVectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GTIntMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_LEIntMaxVectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_LEIntMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "intCompareOpProvider") + static void UNSIGNED_GEIntMaxVectorTests(IntFunction fa, IntFunction fb) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "intCompareOpMaskProvider") + static void UNSIGNED_GEIntMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "intCompareOpProvider") static void LTIntMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { int[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Long128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Long128VectorLoadStoreTests.java index 659f287c811..ac9c301e013 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java index 984e2ff7991..a43ae55535f 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java @@ -966,8 +966,9 @@ public Object[][] longUnaryOpShuffleMaskProvider() { static final List> LONG_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { long[] a = new long[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (long)RAND.nextInt(m); + a[i] = (long)RAND.nextInt(upper); } return a; }) @@ -1028,6 +1029,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (long)i); }), + withToString("long[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(i - (s * BUFFER_REPS / 2))); + }), withToString("long[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (long)(i + 1)); @@ -1147,6 +1152,46 @@ static void replaceZero(long[] a, boolean[] mask, long v) { } } + static boolean eq(long a, long b) { + return a == b; + } + + static boolean neq(long a, long b) { + return a != b; + } + + static boolean lt(long a, long b) { + return a < b; + } + + static boolean le(long a, long b) { + return a <= b; + } + + static boolean gt(long a, long b) { + return a > b; + } + + static boolean ge(long a, long b) { + return a >= b; + } + + static boolean ult(long a, long b) { + return Long.compareUnsigned(a, b) < 0; + } + + static boolean ule(long a, long b) { + return Long.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(long a, long b) { + return Long.compareUnsigned(a, b) > 0; + } + + static boolean uge(long a, long b) { + return Long.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3324,7 +3369,7 @@ static void LTLong128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3344,7 +3389,7 @@ static void ltLong128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3367,7 +3412,7 @@ static void LTLong128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3410,7 +3455,7 @@ static void GTLong128VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3430,7 +3475,7 @@ static void EQLong128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3450,7 +3495,7 @@ static void eqLong128VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3473,7 +3518,7 @@ static void EQLong128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3516,7 +3561,7 @@ static void NELong128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3559,7 +3604,7 @@ static void LELong128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3602,13 +3647,201 @@ static void GELong128VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LTLong128VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LTLong128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GTLong128VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GTLong128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LELong128VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LELong128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GELong128VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GELong128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "longCompareOpProvider") static void LTLong128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { long[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Long256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Long256VectorLoadStoreTests.java index 18d6d80c940..9ff51cb89fc 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java index f541341d41a..b9ca9e09d8f 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java @@ -966,8 +966,9 @@ public Object[][] longUnaryOpShuffleMaskProvider() { static final List> LONG_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { long[] a = new long[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (long)RAND.nextInt(m); + a[i] = (long)RAND.nextInt(upper); } return a; }) @@ -1028,6 +1029,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (long)i); }), + withToString("long[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(i - (s * BUFFER_REPS / 2))); + }), withToString("long[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (long)(i + 1)); @@ -1147,6 +1152,46 @@ static void replaceZero(long[] a, boolean[] mask, long v) { } } + static boolean eq(long a, long b) { + return a == b; + } + + static boolean neq(long a, long b) { + return a != b; + } + + static boolean lt(long a, long b) { + return a < b; + } + + static boolean le(long a, long b) { + return a <= b; + } + + static boolean gt(long a, long b) { + return a > b; + } + + static boolean ge(long a, long b) { + return a >= b; + } + + static boolean ult(long a, long b) { + return Long.compareUnsigned(a, b) < 0; + } + + static boolean ule(long a, long b) { + return Long.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(long a, long b) { + return Long.compareUnsigned(a, b) > 0; + } + + static boolean uge(long a, long b) { + return Long.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3324,7 +3369,7 @@ static void LTLong256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3344,7 +3389,7 @@ static void ltLong256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3367,7 +3412,7 @@ static void LTLong256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3410,7 +3455,7 @@ static void GTLong256VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3430,7 +3475,7 @@ static void EQLong256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3450,7 +3495,7 @@ static void eqLong256VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3473,7 +3518,7 @@ static void EQLong256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3516,7 +3561,7 @@ static void NELong256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3559,7 +3604,7 @@ static void LELong256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3602,13 +3647,201 @@ static void GELong256VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LTLong256VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LTLong256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GTLong256VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GTLong256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LELong256VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LELong256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GELong256VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GELong256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "longCompareOpProvider") static void LTLong256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { long[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Long512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Long512VectorLoadStoreTests.java index a1730c4f8e9..55141360169 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java index 25151061f92..4988b87e915 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java @@ -966,8 +966,9 @@ public Object[][] longUnaryOpShuffleMaskProvider() { static final List> LONG_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { long[] a = new long[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (long)RAND.nextInt(m); + a[i] = (long)RAND.nextInt(upper); } return a; }) @@ -1028,6 +1029,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (long)i); }), + withToString("long[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(i - (s * BUFFER_REPS / 2))); + }), withToString("long[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (long)(i + 1)); @@ -1147,6 +1152,46 @@ static void replaceZero(long[] a, boolean[] mask, long v) { } } + static boolean eq(long a, long b) { + return a == b; + } + + static boolean neq(long a, long b) { + return a != b; + } + + static boolean lt(long a, long b) { + return a < b; + } + + static boolean le(long a, long b) { + return a <= b; + } + + static boolean gt(long a, long b) { + return a > b; + } + + static boolean ge(long a, long b) { + return a >= b; + } + + static boolean ult(long a, long b) { + return Long.compareUnsigned(a, b) < 0; + } + + static boolean ule(long a, long b) { + return Long.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(long a, long b) { + return Long.compareUnsigned(a, b) > 0; + } + + static boolean uge(long a, long b) { + return Long.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3324,7 +3369,7 @@ static void LTLong512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3344,7 +3389,7 @@ static void ltLong512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3367,7 +3412,7 @@ static void LTLong512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3410,7 +3455,7 @@ static void GTLong512VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3430,7 +3475,7 @@ static void EQLong512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3450,7 +3495,7 @@ static void eqLong512VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3473,7 +3518,7 @@ static void EQLong512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3516,7 +3561,7 @@ static void NELong512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3559,7 +3604,7 @@ static void LELong512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3602,13 +3647,201 @@ static void GELong512VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LTLong512VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LTLong512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GTLong512VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GTLong512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LELong512VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LELong512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GELong512VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GELong512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "longCompareOpProvider") static void LTLong512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { long[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Long64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Long64VectorLoadStoreTests.java index 8004dbabd7d..9d6b0764b4c 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorLoadStoreTests.java @@ -959,4 +959,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java index c1310fcf917..abb903b031d 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java @@ -966,8 +966,9 @@ public Object[][] longUnaryOpShuffleMaskProvider() { static final List> LONG_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { long[] a = new long[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (long)RAND.nextInt(m); + a[i] = (long)RAND.nextInt(upper); } return a; }) @@ -1028,6 +1029,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (long)i); }), + withToString("long[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(i - (s * BUFFER_REPS / 2))); + }), withToString("long[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (long)(i + 1)); @@ -1147,6 +1152,46 @@ static void replaceZero(long[] a, boolean[] mask, long v) { } } + static boolean eq(long a, long b) { + return a == b; + } + + static boolean neq(long a, long b) { + return a != b; + } + + static boolean lt(long a, long b) { + return a < b; + } + + static boolean le(long a, long b) { + return a <= b; + } + + static boolean gt(long a, long b) { + return a > b; + } + + static boolean ge(long a, long b) { + return a >= b; + } + + static boolean ult(long a, long b) { + return Long.compareUnsigned(a, b) < 0; + } + + static boolean ule(long a, long b) { + return Long.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(long a, long b) { + return Long.compareUnsigned(a, b) > 0; + } + + static boolean uge(long a, long b) { + return Long.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3324,7 +3369,7 @@ static void LTLong64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3344,7 +3389,7 @@ static void ltLong64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3367,7 +3412,7 @@ static void LTLong64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3410,7 +3455,7 @@ static void GTLong64VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3430,7 +3475,7 @@ static void EQLong64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3450,7 +3495,7 @@ static void eqLong64VectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3473,7 +3518,7 @@ static void EQLong64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3516,7 +3561,7 @@ static void NELong64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3559,7 +3604,7 @@ static void LELong64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3602,13 +3647,201 @@ static void GELong64VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LTLong64VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LTLong64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GTLong64VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GTLong64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LELong64VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LELong64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GELong64VectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GELong64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "longCompareOpProvider") static void LTLong64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { long[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorLoadStoreTests.java index 86ed549c6c0..f1952a0a226 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorLoadStoreTests.java @@ -968,4 +968,7 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + } diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java index cb6679b9070..31b089e522c 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java @@ -971,8 +971,9 @@ public Object[][] longUnaryOpShuffleMaskProvider() { static final List> LONG_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { long[] a = new long[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (long)RAND.nextInt(m); + a[i] = (long)RAND.nextInt(upper); } return a; }) @@ -1033,6 +1034,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (long)i); }), + withToString("long[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(i - (s * BUFFER_REPS / 2))); + }), withToString("long[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (long)(i + 1)); @@ -1152,6 +1157,46 @@ static void replaceZero(long[] a, boolean[] mask, long v) { } } + static boolean eq(long a, long b) { + return a == b; + } + + static boolean neq(long a, long b) { + return a != b; + } + + static boolean lt(long a, long b) { + return a < b; + } + + static boolean le(long a, long b) { + return a <= b; + } + + static boolean gt(long a, long b) { + return a > b; + } + + static boolean ge(long a, long b) { + return a >= b; + } + + static boolean ult(long a, long b) { + return Long.compareUnsigned(a, b) < 0; + } + + static boolean ule(long a, long b) { + return Long.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(long a, long b) { + return Long.compareUnsigned(a, b) > 0; + } + + static boolean uge(long a, long b) { + return Long.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3329,7 +3374,7 @@ static void LTLongMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3349,7 +3394,7 @@ static void ltLongMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3372,7 +3417,7 @@ static void LTLongMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3415,7 +3460,7 @@ static void GTLongMaxVectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3435,7 +3480,7 @@ static void EQLongMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3455,7 +3500,7 @@ static void eqLongMaxVectorTests(IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3478,7 +3523,7 @@ static void EQLongMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3521,7 +3566,7 @@ static void NELongMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3564,7 +3609,7 @@ static void LELongMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction fb) // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3607,13 +3652,201 @@ static void GELongMaxVectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LTLongMaxVectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LTLongMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GTLongMaxVectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GTLongMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_LELongMaxVectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_LELongMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "longCompareOpProvider") + static void UNSIGNED_GELongMaxVectorTests(IntFunction fa, IntFunction fb) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "longCompareOpMaskProvider") + static void UNSIGNED_GELongMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "longCompareOpProvider") static void LTLongMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { long[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Short128VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Short128VectorLoadStoreTests.java index 756a6595297..79ac054c446 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorLoadStoreTests.java @@ -959,4 +959,251 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i) { + return ShortVector.fromCharArray(SPECIES, a, i); + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i, VectorMask m) { + return ShortVector.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i, VectorMask m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + } diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java index 97ae371a730..fb7ff14fe77 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java @@ -970,8 +970,9 @@ public Object[][] shortUnaryOpShuffleMaskProvider() { static final List> SHORT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { short[] a = new short[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (short)RAND.nextInt(m); + a[i] = (short)RAND.nextInt(upper); } return a; }) @@ -1032,6 +1033,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (short)i); }), + withToString("short[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(i - (s * BUFFER_REPS / 2))); + }), withToString("short[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (short)(i + 1)); @@ -1155,6 +1160,46 @@ static void replaceZero(short[] a, boolean[] mask, short v) { } } + static boolean eq(short a, short b) { + return a == b; + } + + static boolean neq(short a, short b) { + return a != b; + } + + static boolean lt(short a, short b) { + return a < b; + } + + static boolean le(short a, short b) { + return a <= b; + } + + static boolean gt(short a, short b) { + return a > b; + } + + static boolean ge(short a, short b) { + return a >= b; + } + + static boolean ult(short a, short b) { + return Short.compareUnsigned(a, b) < 0; + } + + static boolean ule(short a, short b) { + return Short.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(short a, short b) { + return Short.compareUnsigned(a, b) > 0; + } + + static boolean uge(short a, short b) { + return Short.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3327,7 +3372,7 @@ static void LTShort128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3347,7 +3392,7 @@ static void ltShort128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3370,7 +3415,7 @@ static void LTShort128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3413,7 +3458,7 @@ static void GTShort128VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3433,7 +3478,7 @@ static void EQShort128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3453,7 +3498,7 @@ static void eqShort128VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3476,7 +3521,7 @@ static void EQShort128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3519,7 +3564,7 @@ static void NEShort128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3562,7 +3607,7 @@ static void LEShort128VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3605,13 +3650,201 @@ static void GEShort128VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LTShort128VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LTShort128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GTShort128VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GTShort128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LEShort128VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LEShort128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GEShort128VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GEShort128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "shortCompareOpProvider") static void LTShort128VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { short[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Short256VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Short256VectorLoadStoreTests.java index ff4defde6f1..96ee2daa848 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorLoadStoreTests.java @@ -959,4 +959,251 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i) { + return ShortVector.fromCharArray(SPECIES, a, i); + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i, VectorMask m) { + return ShortVector.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i, VectorMask m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + } diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java index 0a3da47a9f1..a83cf81ca07 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java @@ -970,8 +970,9 @@ public Object[][] shortUnaryOpShuffleMaskProvider() { static final List> SHORT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { short[] a = new short[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (short)RAND.nextInt(m); + a[i] = (short)RAND.nextInt(upper); } return a; }) @@ -1032,6 +1033,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (short)i); }), + withToString("short[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(i - (s * BUFFER_REPS / 2))); + }), withToString("short[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (short)(i + 1)); @@ -1155,6 +1160,46 @@ static void replaceZero(short[] a, boolean[] mask, short v) { } } + static boolean eq(short a, short b) { + return a == b; + } + + static boolean neq(short a, short b) { + return a != b; + } + + static boolean lt(short a, short b) { + return a < b; + } + + static boolean le(short a, short b) { + return a <= b; + } + + static boolean gt(short a, short b) { + return a > b; + } + + static boolean ge(short a, short b) { + return a >= b; + } + + static boolean ult(short a, short b) { + return Short.compareUnsigned(a, b) < 0; + } + + static boolean ule(short a, short b) { + return Short.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(short a, short b) { + return Short.compareUnsigned(a, b) > 0; + } + + static boolean uge(short a, short b) { + return Short.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3327,7 +3372,7 @@ static void LTShort256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3347,7 +3392,7 @@ static void ltShort256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3370,7 +3415,7 @@ static void LTShort256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3413,7 +3458,7 @@ static void GTShort256VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3433,7 +3478,7 @@ static void EQShort256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3453,7 +3498,7 @@ static void eqShort256VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3476,7 +3521,7 @@ static void EQShort256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3519,7 +3564,7 @@ static void NEShort256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3562,7 +3607,7 @@ static void LEShort256VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3605,13 +3650,201 @@ static void GEShort256VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LTShort256VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LTShort256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GTShort256VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GTShort256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LEShort256VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LEShort256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GEShort256VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GEShort256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "shortCompareOpProvider") static void LTShort256VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { short[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Short512VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Short512VectorLoadStoreTests.java index 67d964e862d..fefa0e937ed 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorLoadStoreTests.java @@ -959,4 +959,251 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i) { + return ShortVector.fromCharArray(SPECIES, a, i); + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i, VectorMask m) { + return ShortVector.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i, VectorMask m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + } diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java index 7d46134f9a1..8313eb16e66 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java @@ -970,8 +970,9 @@ public Object[][] shortUnaryOpShuffleMaskProvider() { static final List> SHORT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { short[] a = new short[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (short)RAND.nextInt(m); + a[i] = (short)RAND.nextInt(upper); } return a; }) @@ -1032,6 +1033,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (short)i); }), + withToString("short[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(i - (s * BUFFER_REPS / 2))); + }), withToString("short[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (short)(i + 1)); @@ -1155,6 +1160,46 @@ static void replaceZero(short[] a, boolean[] mask, short v) { } } + static boolean eq(short a, short b) { + return a == b; + } + + static boolean neq(short a, short b) { + return a != b; + } + + static boolean lt(short a, short b) { + return a < b; + } + + static boolean le(short a, short b) { + return a <= b; + } + + static boolean gt(short a, short b) { + return a > b; + } + + static boolean ge(short a, short b) { + return a >= b; + } + + static boolean ult(short a, short b) { + return Short.compareUnsigned(a, b) < 0; + } + + static boolean ule(short a, short b) { + return Short.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(short a, short b) { + return Short.compareUnsigned(a, b) > 0; + } + + static boolean uge(short a, short b) { + return Short.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3327,7 +3372,7 @@ static void LTShort512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3347,7 +3392,7 @@ static void ltShort512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3370,7 +3415,7 @@ static void LTShort512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3413,7 +3458,7 @@ static void GTShort512VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3433,7 +3478,7 @@ static void EQShort512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3453,7 +3498,7 @@ static void eqShort512VectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3476,7 +3521,7 @@ static void EQShort512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3519,7 +3564,7 @@ static void NEShort512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3562,7 +3607,7 @@ static void LEShort512VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3605,13 +3650,201 @@ static void GEShort512VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LTShort512VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LTShort512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GTShort512VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GTShort512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LEShort512VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LEShort512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GEShort512VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GEShort512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "shortCompareOpProvider") static void LTShort512VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { short[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/Short64VectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/Short64VectorLoadStoreTests.java index f88fe9c0279..c277dfbc8f4 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorLoadStoreTests.java @@ -959,4 +959,251 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i) { + return ShortVector.fromCharArray(SPECIES, a, i); + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i, VectorMask m) { + return ShortVector.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i, VectorMask m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + } diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java index c4972418fba..cadee84f5cc 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java @@ -970,8 +970,9 @@ public Object[][] shortUnaryOpShuffleMaskProvider() { static final List> SHORT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { short[] a = new short[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (short)RAND.nextInt(m); + a[i] = (short)RAND.nextInt(upper); } return a; }) @@ -1032,6 +1033,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (short)i); }), + withToString("short[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(i - (s * BUFFER_REPS / 2))); + }), withToString("short[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (short)(i + 1)); @@ -1155,6 +1160,46 @@ static void replaceZero(short[] a, boolean[] mask, short v) { } } + static boolean eq(short a, short b) { + return a == b; + } + + static boolean neq(short a, short b) { + return a != b; + } + + static boolean lt(short a, short b) { + return a < b; + } + + static boolean le(short a, short b) { + return a <= b; + } + + static boolean gt(short a, short b) { + return a > b; + } + + static boolean ge(short a, short b) { + return a >= b; + } + + static boolean ult(short a, short b) { + return Short.compareUnsigned(a, b) < 0; + } + + static boolean ule(short a, short b) { + return Short.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(short a, short b) { + return Short.compareUnsigned(a, b) > 0; + } + + static boolean uge(short a, short b) { + return Short.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3327,7 +3372,7 @@ static void LTShort64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3347,7 +3392,7 @@ static void ltShort64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3370,7 +3415,7 @@ static void LTShort64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3413,7 +3458,7 @@ static void GTShort64VectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3433,7 +3478,7 @@ static void EQShort64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3453,7 +3498,7 @@ static void eqShort64VectorTests(IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3476,7 +3521,7 @@ static void EQShort64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3519,7 +3564,7 @@ static void NEShort64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3562,7 +3607,7 @@ static void LEShort64VectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction f // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3605,13 +3650,201 @@ static void GEShort64VectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LTShort64VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LTShort64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GTShort64VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GTShort64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LEShort64VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LEShort64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GEShort64VectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GEShort64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "shortCompareOpProvider") static void LTShort64VectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { short[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorLoadStoreTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorLoadStoreTests.java index d9c706c477f..0cc0eaba483 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorLoadStoreTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorLoadStoreTests.java @@ -968,4 +968,251 @@ static void loadStoreShuffle() { Assert.assertEquals(r, a); } } + + + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i) { + return ShortVector.fromCharArray(SPECIES, a, i); + } + + @DontInline + static ShortVector fromCharArray(char[] a, int i, VectorMask m) { + return ShortVector.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray(ShortVector v, char[] a, int i, VectorMask m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + } diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java index 603afb6a8ae..ad3008a536d 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java @@ -975,8 +975,9 @@ public Object[][] shortUnaryOpShuffleMaskProvider() { static final List> SHORT_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { short[] a = new short[l]; + int upper = m; for (int i = 0; i < 1; i++) { - a[i] = (short)RAND.nextInt(m); + a[i] = (short)RAND.nextInt(upper); } return a; }) @@ -1037,6 +1038,10 @@ public Object[][] scatterMaskedOpIndexProvider() { return fill(s * BUFFER_REPS, i -> (short)i); }), + withToString("short[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(i - (s * BUFFER_REPS / 2))); + }), withToString("short[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> (short)(i + 1)); @@ -1160,6 +1165,46 @@ static void replaceZero(short[] a, boolean[] mask, short v) { } } + static boolean eq(short a, short b) { + return a == b; + } + + static boolean neq(short a, short b) { + return a != b; + } + + static boolean lt(short a, short b) { + return a < b; + } + + static boolean le(short a, short b) { + return a <= b; + } + + static boolean gt(short a, short b) { + return a > b; + } + + static boolean ge(short a, short b) { + return a >= b; + } + + static boolean ult(short a, short b) { + return Short.compareUnsigned(a, b) < 0; + } + + static boolean ule(short a, short b) { + return Short.compareUnsigned(a, b) <= 0; + } + + static boolean ugt(short a, short b) { + return Short.compareUnsigned(a, b) > 0; + } + + static boolean uge(short a, short b) { + return Short.compareUnsigned(a, b) >= 0; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3332,7 +3377,7 @@ static void LTShortMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3352,7 +3397,7 @@ static void ltShortMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j])); } } } @@ -3375,7 +3420,7 @@ static void LTShortMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] > b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j])); } } } @@ -3418,7 +3463,7 @@ static void GTShortMaxVectorTestsMasked(IntFunction fa, IntFunction b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j])); } } } @@ -3438,7 +3483,7 @@ static void EQShortMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3458,7 +3503,7 @@ static void eqShortMaxVectorTests(IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j])); } } } @@ -3481,7 +3526,7 @@ static void EQShortMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] != b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j])); } } } @@ -3524,7 +3569,7 @@ static void NEShortMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] <= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j])); } } } @@ -3567,7 +3612,7 @@ static void LEShortMaxVectorTestsMasked(IntFunction fa, IntFunction fa, IntFunction // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] >= b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j])); } } } @@ -3610,13 +3655,201 @@ static void GEShortMaxVectorTestsMasked(IntFunction fa, IntFunction= b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LTShortMaxVectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ult(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LTShortMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ult(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GTShortMaxVectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ugt(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GTShortMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GT, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ugt(a[i + j], b[i + j])); } } } } + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_LEShortMaxVectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), ule(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_LEShortMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_LE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && ule(a[i + j], b[i + j])); + } + } + } + } + + + + + @Test(dataProvider = "shortCompareOpProvider") + static void UNSIGNED_GEShortMaxVectorTests(IntFunction fa, IntFunction fb) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), uge(a[i + j], b[i + j])); + } + } + } + } + + + + @Test(dataProvider = "shortCompareOpMaskProvider") + static void UNSIGNED_GEShortMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + VectorMask mv = av.compare(VectorOperators.UNSIGNED_GE, bv, vmask); + + // Check results as part of computation. + for (int j = 0; j < SPECIES.length(); j++) { + Assert.assertEquals(mv.laneIsSet(j), mask[j] && uge(a[i + j], b[i + j])); + } + } + } + } + + + @Test(dataProvider = "shortCompareOpProvider") static void LTShortMaxVectorTestsBroadcastSmokeTest(IntFunction fa, IntFunction fb) { short[] a = fa.apply(SPECIES.length()); diff --git a/test/jdk/jdk/incubator/vector/gen-template.sh b/test/jdk/jdk/incubator/vector/gen-template.sh index ef74c897541..22513b31ba9 100644 --- a/test/jdk/jdk/incubator/vector/gen-template.sh +++ b/test/jdk/jdk/incubator/vector/gen-template.sh @@ -481,12 +481,19 @@ gen_op_tmpl $test_template "IS_NAN" "\$Boxtype\$.isNaN(a)" "FP" gen_op_tmpl $test_template "IS_INFINITE" "\$Boxtype\$.isInfinite(a)" "FP" # Compares -gen_compare_op "LT+lt" "<" -gen_compare_op "GT" ">" -gen_compare_op "EQ+eq" "==" -gen_compare_op "NE" "!=" -gen_compare_op "LE" "<=" -gen_compare_op "GE" ">=" +gen_compare_op "LT+lt" "lt" +gen_compare_op "GT" "gt" +gen_compare_op "EQ+eq" "eq" +gen_compare_op "NE" "neq" +gen_compare_op "LE" "le" +gen_compare_op "GE" "ge" + +gen_compare_op "UNSIGNED_LT" "ult" "BITWISE" +gen_compare_op "UNSIGNED_GT" "ugt" "BITWISE" +gen_compare_op "UNSIGNED_LE" "ule" "BITWISE" +gen_compare_op "UNSIGNED_GE" "uge" "BITWISE" + + gen_compare_bcst_op "LT" "<" gen_compare_bcst_op "EQ" "==" diff --git a/test/jdk/jdk/incubator/vector/gen-tests.sh b/test/jdk/jdk/incubator/vector/gen-tests.sh index e797d1541f9..15fcc00cca0 100644 --- a/test/jdk/jdk/incubator/vector/gen-tests.sh +++ b/test/jdk/jdk/incubator/vector/gen-tests.sh @@ -153,6 +153,9 @@ do fpvectortype=${typeprefix}${Fptype}${bits}Vector shape=S${bits}Bit Shape=S_${bits}_BIT + if [[ "${vectortype}" == "ByteMaxVector" ]]; then + args="$args -KByteMax" + fi bitargs="$args -Dbits=$bits -Dvectortype=$vectortype -Dvectorteststype=$vectorteststype -Dvectorbenchtype=$vectorbenchtype -Dmasktype=$masktype -Dbitsvectortype=$bitsvectortype -Dfpvectortype=$fpvectortype -Dshape=$shape -DShape=$Shape" if [ $bits == 'Max' ]; then bitargs="$bitargs -KMaxBit" @@ -225,6 +228,9 @@ do fpvectortype=${typeprefix}${Fptype}${bits}Vector shape=S${bits}Bit Shape=S_${bits}_BIT + if [[ "${vectortype}" == "ByteMaxVector" ]]; then + args="$args -KByteMax" + fi bitargs="$args -Dbits=$bits -Dvectortype=$vectortype -Dvectorteststype=$vectorteststype -Dvectorbenchtype=$vectorbenchtype -Dmasktype=$masktype -Dbitsvectortype=$bitsvectortype -Dfpvectortype=$fpvectortype -Dshape=$shape -DShape=$Shape" if [ $bits == 'Max' ]; then bitargs="$bitargs -KMaxBit" diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Compare-Masked.template b/test/jdk/jdk/incubator/vector/templates/Unit-Compare-Masked.template index 07a89a9fd0b..3b201c630b5 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Compare-Masked.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Compare-Masked.template @@ -15,7 +15,7 @@ // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] [[TEST_OP]] b[i + j])); + Assert.assertEquals(mv.laneIsSet(j), mask[j] && [[TEST_OP]](a[i + j], b[i + j])); } } } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Compare.template b/test/jdk/jdk/incubator/vector/templates/Unit-Compare.template index 49e867804e4..8132a850be6 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Compare.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Compare.template @@ -12,7 +12,7 @@ // Check results as part of computation. for (int j = 0; j < SPECIES.length(); j++) { - Assert.assertEquals(mv.laneIsSet(j), a[i + j] [[TEST_OP]] b[i + j]); + Assert.assertEquals(mv.laneIsSet(j), [[TEST_OP]](a[i + j], b[i + j])); } } } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template index d7c428fce12..894d3c64c43 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template @@ -1184,8 +1184,13 @@ public class $vectorteststype$ extends AbstractVectorTest { static final List> $TYPE$_SHUFFLE_GENERATORS = List.of( withToStringBi("shuffle[random]", (Integer l, Integer m) -> { $type$[] a = new $type$[l]; +#if[ByteMax] + int upper = Math.min(Byte.MAX_VALUE + 1, m); +#else[ByteMax] + int upper = m; +#end[ByteMax] for (int i = 0; i < 1; i++) { - a[i] = ($type$)RAND.nextInt(m); + a[i] = ($type$)RAND.nextInt(upper); } return a; }) @@ -1247,6 +1252,10 @@ public class $vectorteststype$ extends AbstractVectorTest { return fill(s * BUFFER_REPS, i -> ($type$)i); }), + withToString("$type$[i - length / 2]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> ($type$)(i - (s * BUFFER_REPS / 2))); + }), withToString("$type$[i + 1]", (int s) -> { return fill(s * BUFFER_REPS, i -> ($type$)(i + 1)); @@ -1393,6 +1402,48 @@ public class $vectorteststype$ extends AbstractVectorTest { } #end[BITWISE] + static boolean eq($type$ a, $type$ b) { + return a == b; + } + + static boolean neq($type$ a, $type$ b) { + return a != b; + } + + static boolean lt($type$ a, $type$ b) { + return a < b; + } + + static boolean le($type$ a, $type$ b) { + return a <= b; + } + + static boolean gt($type$ a, $type$ b) { + return a > b; + } + + static boolean ge($type$ a, $type$ b) { + return a >= b; + } + +#if[!FP] + static boolean ult($type$ a, $type$ b) { + return $Boxtype$.compareUnsigned(a, b) < 0; + } + + static boolean ule($type$ a, $type$ b) { + return $Boxtype$.compareUnsigned(a, b) <= 0; + } + + static boolean ugt($type$ a, $type$ b) { + return $Boxtype$.compareUnsigned(a, b) > 0; + } + + static boolean uge($type$ a, $type$ b) { + return $Boxtype$.compareUnsigned(a, b) >= 0; + } +#end[!FP] + @Test static void smokeTest1() { $abstractvectortype$ three = $abstractvectortype$.broadcast(SPECIES, (byte)-3); diff --git a/test/jdk/jdk/incubator/vector/templates/X-LoadStoreTest.java.template b/test/jdk/jdk/incubator/vector/templates/X-LoadStoreTest.java.template index 141ea83d3a9..8e63618b18f 100644 --- a/test/jdk/jdk/incubator/vector/templates/X-LoadStoreTest.java.template +++ b/test/jdk/jdk/incubator/vector/templates/X-LoadStoreTest.java.template @@ -991,4 +991,342 @@ public class $vectorteststype$ extends AbstractVectorTest { Assert.assertEquals(r, a); } } + + +#if[short] + static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); + } + } + + static final List> CHAR_GENERATORS = List.of( + withToString("char[i * 5]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (char)(i * 5)); + }), + withToString("char[i + 1]", (int s) -> { + return fillChar(s * BUFFER_REPS, + i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); + }) + ); + + @DataProvider + public Object[][] charProvider() { + return CHAR_GENERATORS.stream(). + map(f -> new Object[]{f}). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi}; + }). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { + return new Object[] {fa, fm}; + })). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] charMaskProviderForIOOBE() { + var f = CHAR_GENERATORS.get(0); + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { + return new Object[] {f, fi, fm}; + })). + toArray(Object[][]::new); + } + + interface ToCharF { + char apply(int i); + } + + static char[] fillChar(int s , ToCharF f) { + return fillChar(new char[s], f); + } + + static char[] fillChar(char[] a, ToCharF f) { + for (int i = 0; i < a.length; i++) { + a[i] = f.apply(i); + } + return a; + } + + @DontInline + static $abstractvectortype$ fromCharArray(char[] a, int i) { + return $abstractvectortype$.fromCharArray(SPECIES, a, i); + } + + @DontInline + static $abstractvectortype$ fromCharArray(char[] a, int i, VectorMask<$Boxtype$> m) { + return $abstractvectortype$.fromCharArray(SPECIES, a, i, m); + } + + @DontInline + static void intoCharArray($abstractvectortype$ v, char[] a, int i) { + v.intoCharArray(a, i); + } + + @DontInline + static void intoCharArray($abstractvectortype$ v, char[] a, int i, VectorMask<$Boxtype$> m) { + v.intoCharArray(a, i, m); + } + + @Test(dataProvider = "charProvider") + static void loadStoreCharArray(IntFunction fa) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i); + } + } + Assert.assertEquals(a, r); + } + + @Test(dataProvider = "charProviderForIOOBE") + static void loadCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = fromCharArray(a, i); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + fromCharArray(a, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charProviderForIOOBE") + static void storeCharArrayIOOBE(IntFunction fa, IntFunction fi) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); + try { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0); + intoCharArray(av, r, index); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProvider") + static void loadStoreMaskCharArray(IntFunction fa, + IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, vmask); + av.intoCharArray(r, i); + } + } + assertArraysEquals(a, r, mask); + + + r = new char[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); + av.intoCharArray(r, i, vmask); + } + } + assertArraysEquals(a, r, mask); + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void loadCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = fromCharArray(a, i, vmask); + av.intoCharArray(r, i); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + fromCharArray(a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + + @Test(dataProvider = "charMaskProviderForIOOBE") + static void storeCharArrayMaskIOOBE(IntFunction fa, IntFunction fi, IntFunction fm) { + char[] a = fa.apply(SPECIES.length()); + char[] r = new char[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); + intoCharArray(av, r, i, vmask); + } + } + + int index = fi.apply(a.length); + boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); + try { + $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0); + intoCharArray(av, a, index, vmask); + if (shouldFail) { + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } + } catch (IndexOutOfBoundsException e) { + if (!shouldFail) { + Assert.fail("Unexpected IndexOutOfBoundsException"); + } + } + } + +#end[short] + +#if[byte] + static void assertArraysEquals(boolean[] r, byte[] a) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], (a[i] & 1) == 1); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); + } + } + + static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { + int i = 0; + try { + for (; i < a.length; i++) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); + } + } + + static boolean[] convertToBooleanArray(byte[] a) { + boolean[] r = new boolean[a.length]; + + for (int i = 0; i < a.length; i++) { + r[i] = (a[i] & 1) == 1; + } + + return r; + } + + @Test(dataProvider = "byteProvider") + static void loadByteStoreBooleanArray(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a); + } + + @Test(dataProvider = "byteProvider") + static void loadStoreBooleanArray(IntFunction fa) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i); + } + } + Assert.assertEquals(r, a); + } + + @Test(dataProvider = "byteMaskProvider") + static void loadStoreMaskBooleanArray(IntFunction fa, + IntFunction fm) { + boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); + boolean[] r = new boolean[a.length]; + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromValues(SPECIES, mask); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); + av.intoBooleanArray(r, i); + } + } + assertArraysEquals(r, a, mask); + + + r = new boolean[a.length]; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); + av.intoBooleanArray(r, i, vmask); + } + } + assertArraysEquals(r, a, mask); + } +#end[byte] }