From 709914fc92dd180c8f081ff70ef476554a04f4ce Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Wed, 16 Oct 2024 16:08:02 +0000 Subject: [PATCH] 8338023: Support two vector selectFrom API Reviewed-by: psandoz, epeter, sviswanathan --- src/hotspot/cpu/x86/assembler_x86.cpp | 72 +++-- src/hotspot/cpu/x86/assembler_x86.hpp | 9 +- src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp | 27 ++ src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp | 2 + src/hotspot/cpu/x86/x86.ad | 27 ++ src/hotspot/share/adlc/formssel.cpp | 2 +- src/hotspot/share/classfile/vmIntrinsics.hpp | 11 + src/hotspot/share/opto/c2compiler.cpp | 1 + src/hotspot/share/opto/classes.hpp | 1 + src/hotspot/share/opto/library_call.cpp | 2 + src/hotspot/share/opto/library_call.hpp | 1 + src/hotspot/share/opto/matcher.cpp | 1 + src/hotspot/share/opto/vectorIntrinsics.cpp | 185 ++++++++++++- src/hotspot/share/opto/vectornode.cpp | 2 + src/hotspot/share/opto/vectornode.hpp | 15 ++ .../jdk/internal/vm/vector/VectorSupport.java | 18 ++ .../jdk/incubator/vector/Byte128Vector.java | 7 + .../jdk/incubator/vector/Byte256Vector.java | 7 + .../jdk/incubator/vector/Byte512Vector.java | 7 + .../jdk/incubator/vector/Byte64Vector.java | 7 + .../jdk/incubator/vector/ByteMaxVector.java | 7 + .../jdk/incubator/vector/ByteVector.java | 29 ++ .../jdk/incubator/vector/Double128Vector.java | 7 + .../jdk/incubator/vector/Double256Vector.java | 7 + .../jdk/incubator/vector/Double512Vector.java | 7 + .../jdk/incubator/vector/Double64Vector.java | 7 + .../jdk/incubator/vector/DoubleMaxVector.java | 7 + .../jdk/incubator/vector/DoubleVector.java | 29 ++ .../jdk/incubator/vector/Float128Vector.java | 7 + .../jdk/incubator/vector/Float256Vector.java | 7 + .../jdk/incubator/vector/Float512Vector.java | 7 + .../jdk/incubator/vector/Float64Vector.java | 7 + .../jdk/incubator/vector/FloatMaxVector.java | 7 + .../jdk/incubator/vector/FloatVector.java | 29 ++ .../jdk/incubator/vector/Int128Vector.java | 7 + .../jdk/incubator/vector/Int256Vector.java | 7 + .../jdk/incubator/vector/Int512Vector.java | 7 + .../jdk/incubator/vector/Int64Vector.java | 7 + .../jdk/incubator/vector/IntMaxVector.java | 7 + .../jdk/incubator/vector/IntVector.java | 29 ++ .../jdk/incubator/vector/Long128Vector.java | 7 + .../jdk/incubator/vector/Long256Vector.java | 7 + .../jdk/incubator/vector/Long512Vector.java | 7 + .../jdk/incubator/vector/Long64Vector.java | 7 + .../jdk/incubator/vector/LongMaxVector.java | 7 + .../jdk/incubator/vector/LongVector.java | 29 ++ .../jdk/incubator/vector/Short128Vector.java | 7 + .../jdk/incubator/vector/Short256Vector.java | 7 + .../jdk/incubator/vector/Short512Vector.java | 7 + .../jdk/incubator/vector/Short64Vector.java | 7 + .../jdk/incubator/vector/ShortMaxVector.java | 7 + .../jdk/incubator/vector/ShortVector.java | 29 ++ .../classes/jdk/incubator/vector/Vector.java | 55 ++++ .../jdk/incubator/vector/VectorOperators.java | 1 + .../incubator/vector/X-Vector.java.template | 29 ++ .../vector/X-VectorBits.java.template | 7 + .../incubator/vector/Byte128VectorTests.java | 55 ++++ .../incubator/vector/Byte256VectorTests.java | 55 ++++ .../incubator/vector/Byte512VectorTests.java | 55 ++++ .../incubator/vector/Byte64VectorTests.java | 55 ++++ .../incubator/vector/ByteMaxVectorTests.java | 55 ++++ .../vector/Double128VectorTests.java | 55 ++++ .../vector/Double256VectorTests.java | 55 ++++ .../vector/Double512VectorTests.java | 55 ++++ .../incubator/vector/Double64VectorTests.java | 55 ++++ .../vector/DoubleMaxVectorTests.java | 55 ++++ .../incubator/vector/Float128VectorTests.java | 55 ++++ .../incubator/vector/Float256VectorTests.java | 55 ++++ .../incubator/vector/Float512VectorTests.java | 55 ++++ .../incubator/vector/Float64VectorTests.java | 55 ++++ .../incubator/vector/FloatMaxVectorTests.java | 55 ++++ .../incubator/vector/Int128VectorTests.java | 55 ++++ .../incubator/vector/Int256VectorTests.java | 55 ++++ .../incubator/vector/Int512VectorTests.java | 55 ++++ .../incubator/vector/Int64VectorTests.java | 55 ++++ .../incubator/vector/IntMaxVectorTests.java | 55 ++++ .../incubator/vector/Long128VectorTests.java | 55 ++++ .../incubator/vector/Long256VectorTests.java | 55 ++++ .../incubator/vector/Long512VectorTests.java | 55 ++++ .../incubator/vector/Long64VectorTests.java | 55 ++++ .../incubator/vector/LongMaxVectorTests.java | 55 ++++ .../incubator/vector/Short128VectorTests.java | 55 ++++ .../incubator/vector/Short256VectorTests.java | 55 ++++ .../incubator/vector/Short512VectorTests.java | 55 ++++ .../incubator/vector/Short64VectorTests.java | 55 ++++ .../incubator/vector/ShortMaxVectorTests.java | 55 ++++ .../templates/Unit-Miscellaneous.template | 18 ++ .../vector/templates/Unit-header.template | 37 +++ .../incubator/vector/SelectFromBenchmark.java | 251 ++++++++++++++++++ 89 files changed, 2788 insertions(+), 20 deletions(-) create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/vector/SelectFromBenchmark.java diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index c1679cd111f..8b61fd27de0 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -4738,22 +4738,6 @@ void Assembler::vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_l emit_int24(0x01, (0xC0 | encode), imm8); } -void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { - assert(VM_Version::supports_evex(), ""); - InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); - attributes.set_is_evex_instruction(); - int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int16(0x76, (0xC0 | encode)); -} - -void Assembler::evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { - assert(VM_Version::supports_avx512_vbmi(), ""); - InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); - attributes.set_is_evex_instruction(); - int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int16(0x7D, (0xC0 | encode)); -} - void Assembler::evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512_vbmi(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); @@ -16103,3 +16087,59 @@ void InstructionAttr::set_address_attributes(int tuple_type, int input_size_in_b _input_size_in_bits = input_size_in_bits; } } + +void Assembler::evpermi2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512_vbmi() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x75, (0xC0 | encode)); +} + +void Assembler::evpermi2w(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512bw() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x75, (0xC0 | encode)); +} + +void Assembler::evpermi2d(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x76, (0xC0 | encode)); +} + +void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x76, (0xC0 | encode)); +} + +void Assembler::evpermi2ps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x77, (0xC0 | encode)); +} + +void Assembler::evpermi2pd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x77, (0xC0 | encode)); +} + +void Assembler::evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512_vbmi(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x7D, (0xC0 | encode)); +} diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index eace7bb9cc1..696fff5e3eb 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -1962,9 +1962,14 @@ private: void vpermilps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpermilpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len); void vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len); - void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); - void evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len); + void evpermi2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermi2w(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermi2d(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermi2ps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermi2pd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void pause(); diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index aba5344b7e4..0eab2de2c64 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -6475,3 +6475,30 @@ void C2_MacroAssembler::vector_rearrange_int_float(BasicType bt, XMMRegister dst vpermps(dst, shuffle, src, vlen_enc); } } + +void C2_MacroAssembler::select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, + XMMRegister src2, int vlen_enc) { + switch(elem_bt) { + case T_BYTE: + evpermi2b(dst, src1, src2, vlen_enc); + break; + case T_SHORT: + evpermi2w(dst, src1, src2, vlen_enc); + break; + case T_INT: + evpermi2d(dst, src1, src2, vlen_enc); + break; + case T_LONG: + evpermi2q(dst, src1, src2, vlen_enc); + break; + case T_FLOAT: + evpermi2ps(dst, src1, src2, vlen_enc); + break; + case T_DOUBLE: + evpermi2pd(dst, src1, src2, vlen_enc); + break; + default: + fatal("Unsupported type %s", type2name(elem_bt)); + break; + } +} diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index af57546b3d1..5744fedcc64 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -505,4 +505,6 @@ public: void vgather8b_offset(BasicType elem_bt, XMMRegister dst, Register base, Register idx_base, Register offset, Register rtmp, int vlen_enc); + void select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc); + #endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index c88fa1ec5ce..7684febb8ae 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1935,6 +1935,20 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { return false; } break; + case Op_SelectFromTwoVector: + if (size_in_bits < 128 || (size_in_bits < 512 && !VM_Version::supports_avx512vl())) { + return false; + } + if (bt == T_SHORT && !VM_Version::supports_avx512bw()) { + return false; + } + if (bt == T_BYTE && !VM_Version::supports_avx512_vbmi()) { + return false; + } + if ((bt == T_INT || bt == T_FLOAT || bt == T_DOUBLE) && !VM_Version::supports_evex()) { + return false; + } + break; case Op_MaskAll: if (!VM_Version::supports_evex()) { return false; @@ -10468,3 +10482,16 @@ instruct DoubleClassCheck_reg_reg_vfpclass(rRegI dst, regD src, kReg ktmp, rFlag %} ins_pipe(pipe_slow); %} + + +instruct vector_selectfrom_twovectors_reg_evex(vec index, vec src1, vec src2) +%{ + match(Set index (SelectFromTwoVector (Binary index src1) src2)); + format %{ "select_from_two_vector $index, $src1, $src2 \t!" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + BasicType bt = Matcher::vector_element_basic_type(this); + __ select_from_two_vectors_evex(bt, $index$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vlen_enc); + %} + ins_pipe(pipe_slow); +%} diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index ac2d3d94153..e7dd00fa390 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -4355,7 +4355,7 @@ bool MatchRule::is_vector() const { "Replicate","ReverseV","ReverseBytesV", "RoundDoubleModeV","RotateLeftV" , "RotateRightV", "LoadVector","StoreVector", "LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked", - "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert", + "SelectFromTwoVector", "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert", "VectorRearrange", "VectorLoadShuffle", "VectorLoadConst", "VectorCastB2X", "VectorCastS2X", "VectorCastI2X", "VectorCastL2X", "VectorCastF2X", "VectorCastD2X", "VectorCastF2HF", "VectorCastHF2F", diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 9bb8b2179ae..54912a5ded7 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -981,6 +981,17 @@ class methodHandle; "Ljdk/internal/vm/vector/VectorSupport$Vector;") \ do_name(vector_ternary_op_name, "ternaryOp") \ \ + do_intrinsic(_VectorSelectFromTwoVectorOp, jdk_internal_vm_vector_VectorSupport, vector_select_from_op_name, vector_select_from_op_sig, F_S) \ + do_signature(vector_select_from_op_sig, "(Ljava/lang/Class;" \ + "Ljava/lang/Class;" \ + "I" \ + "Ljdk/internal/vm/vector/VectorSupport$Vector;" \ + "Ljdk/internal/vm/vector/VectorSupport$Vector;" \ + "Ljdk/internal/vm/vector/VectorSupport$Vector;" \ + "Ljdk/internal/vm/vector/VectorSupport$SelectFromTwoVector;)" \ + "Ljdk/internal/vm/vector/VectorSupport$Vector;") \ + do_name(vector_select_from_op_name, "selectFromTwoVectorOp") \ + \ do_intrinsic(_VectorFromBitsCoerced, jdk_internal_vm_vector_VectorSupport, vector_frombits_coerced_name, vector_frombits_coerced_sig, F_S) \ do_signature(vector_frombits_coerced_sig, "(Ljava/lang/Class;" \ "Ljava/lang/Class;" \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 1a00f17f505..fa0abf2deb1 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -818,6 +818,7 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_VectorLoadMaskedOp: case vmIntrinsics::_VectorStoreOp: case vmIntrinsics::_VectorStoreMaskedOp: + case vmIntrinsics::_VectorSelectFromTwoVectorOp: case vmIntrinsics::_VectorGatherOp: case vmIntrinsics::_VectorScatterOp: case vmIntrinsics::_VectorReductionCoerced: diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index 215e48ef9da..de6d48ebdf9 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -482,6 +482,7 @@ macro(Digit) macro(LowerCase) macro(UpperCase) macro(Whitespace) +macro(SelectFromTwoVector) macro(VectorBox) macro(VectorBoxAllocate) macro(VectorUnbox) diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 49750cd2697..c7c9da18e54 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -755,6 +755,8 @@ bool LibraryCallKit::try_to_inline(int predicate) { return inline_vector_extract(); case vmIntrinsics::_VectorCompressExpand: return inline_vector_compress_expand(); + case vmIntrinsics::_VectorSelectFromTwoVectorOp: + return inline_vector_select_from_two_vectors(); case vmIntrinsics::_IndexVector: return inline_index_vector(); case vmIntrinsics::_IndexPartiallyInUpperRange: diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index c9b2a02d3f1..c5437e3bf73 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -374,6 +374,7 @@ class LibraryCallKit : public GraphKit { bool inline_vector_compress_expand(); bool inline_index_vector(); bool inline_index_partially_in_upper_range(); + bool inline_vector_select_from_two_vectors(); Node* gen_call_to_vector_math(int vector_api_op_id, BasicType bt, int num_elem, Node* opd1, Node* opd2); diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index 2031b09ca9d..920178a0d04 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -2436,6 +2436,7 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) { n->del_req(4); break; } + case Op_SelectFromTwoVector: case Op_LoopLimit: { Node* pair1 = new BinaryNode(n->in(1), n->in(2)); n->set_req(1, pair1); diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 838f87eac01..fe1807b9588 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -2356,9 +2356,10 @@ bool LibraryCallKit::inline_vector_broadcast_int() { } Node* cnt = argument(6); + const TypeInt* cnt_type = cnt->bottom_type()->isa_int(); + ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); - const TypeInt* cnt_type = cnt->bottom_type()->isa_int(); // If CPU supports vector constant rotate instructions pass it directly bool is_const_rotate = is_rotate && cnt_type && cnt_type->is_con() && @@ -2841,6 +2842,188 @@ bool LibraryCallKit::inline_vector_extract() { return true; } +static Node* LowerSelectFromTwoVectorOperation(PhaseGVN& phase, Node* index_vec, Node* src1, Node* src2, const TypeVect* vt) { + int num_elem = vt->length(); + BasicType elem_bt = vt->element_basic_type(); + + // Lower selectFrom operation into its constituent operations. + // SelectFromTwoVectorNode = + // (VectorBlend + // (VectorRearrange SRC1 (WRAPED_INDEX AND (VLEN-1)) + // (VectorRearrange SRC2 (WRAPED_INDEX AND (VLEN-1)) + // MASK) + // Where + // WRAPED_INDEX are computed by wrapping incoming indexes + // to two vector index range [0, VLEN*2) and + // MASK = WRAPED_INDEX < VLEN + // + // IR lowering prevents intrinsification failure and associated argument + // boxing penalties. + // + + const TypeVect* index_vect_type = index_vec->bottom_type()->is_vect(); + BasicType index_elem_bt = index_vect_type->element_basic_type(); + + // Downcast index vector to a type agnostic shuffle representation, shuffle + // indices are held in a byte vector which are later transformed to target + // specific permutation index format by subsequent VectorLoadShuffle. + int cast_vopc = VectorCastNode::opcode(0, index_elem_bt, true); + Node* index_byte_vec = phase.transform(VectorCastNode::make(cast_vopc, index_vec, T_BYTE, num_elem)); + + // Wrap indexes into two vector index range [0, VLEN * 2) + Node* two_vect_lane_cnt_m1 = phase.makecon(TypeInt::make(2 * num_elem - 1)); + Node* bcast_two_vect_lane_cnt_m1_vec = phase.transform(VectorNode::scalar2vector(two_vect_lane_cnt_m1, num_elem, + Type::get_const_basic_type(T_BYTE), false)); + index_byte_vec = phase.transform(VectorNode::make(Op_AndV, index_byte_vec, bcast_two_vect_lane_cnt_m1_vec, + index_byte_vec->bottom_type()->is_vect())); + + // Compute the blend mask for merging two independently permitted vectors + // using shuffle index in two vector index range [0, VLEN * 2). + BoolTest::mask pred = BoolTest::le; + ConINode* pred_node = phase.makecon(TypeInt::make(pred))->as_ConI(); + const TypeVect* vmask_type = TypeVect::makemask(T_BYTE, num_elem); + Node* lane_cnt_m1 = phase.makecon(TypeInt::make(num_elem - 1)); + Node* bcast_lane_cnt_m1_vec = phase.transform(VectorNode::scalar2vector(lane_cnt_m1, num_elem, + Type::get_const_basic_type(T_BYTE), false)); + Node* mask = phase.transform(new VectorMaskCmpNode(pred, index_byte_vec, bcast_lane_cnt_m1_vec, pred_node, vmask_type)); + + // Rearrange expects the indexes to lie within single vector index range [0, VLEN). + index_byte_vec = phase.transform(VectorNode::make(Op_AndV, index_byte_vec, bcast_lane_cnt_m1_vec, + index_byte_vec->bottom_type()->is_vect())); + + // Load indexes from byte vector and appropriately transform them to target + // specific permutation index format. + index_vec = phase.transform(new VectorLoadShuffleNode(index_byte_vec, index_vect_type)); + + vmask_type = TypeVect::makemask(elem_bt, num_elem); + mask = phase.transform(new VectorMaskCastNode(mask, vmask_type)); + + Node* p1 = phase.transform(new VectorRearrangeNode(src1, index_vec)); + Node* p2 = phase.transform(new VectorRearrangeNode(src2, index_vec)); + + return new VectorBlendNode(p2, p1, mask); +} + +// public static +// , +// E> +// V selectFromTwoVectorOp(Class vClass, Class eClass, int length, +// V v1, V v2, V v3, +// SelectFromTwoVector defaultImpl) +bool LibraryCallKit::inline_vector_select_from_two_vectors() { + const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr(); + const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr(); + const TypeInt* vlen = gvn().type(argument(2))->isa_int(); + + if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || vector_klass->const_oop() == nullptr || + elem_klass->const_oop() == nullptr ||!vlen->is_con()) { + log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", + NodeClassNames[argument(0)->Opcode()], + NodeClassNames[argument(1)->Opcode()], + NodeClassNames[argument(2)->Opcode()]); + return false; // not enough info for intrinsification + } + + if (!is_klass_initialized(vector_klass)) { + log_if_needed(" ** klass argument not initialized"); + return false; + } + + ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type(); + if (!elem_type->is_primitive_type()) { + log_if_needed(" ** not a primitive bt=%d", elem_type->basic_type()); + return false; // should be primitive type + } + + int num_elem = vlen->get_con(); + if (!is_power_of_2(num_elem)) { + log_if_needed(" ** vlen is not power of two=%d", num_elem); + return false; + } + + BasicType elem_bt = elem_type->basic_type(); + BasicType index_elem_bt = elem_bt; + if (elem_bt == T_FLOAT) { + index_elem_bt = T_INT; + } else if (elem_bt == T_DOUBLE) { + index_elem_bt = T_LONG; + } + + bool lowerSelectFromOp = false; + if (!arch_supports_vector(Op_SelectFromTwoVector, num_elem, elem_bt, VecMaskNotUsed)) { + int cast_vopc = VectorCastNode::opcode(-1, elem_bt, true); + if (!arch_supports_vector(Op_VectorMaskCmp, num_elem, T_BYTE, VecMaskNotUsed) || + !arch_supports_vector(Op_AndV, num_elem, T_BYTE, VecMaskNotUsed) || + !arch_supports_vector(Op_VectorMaskCast, num_elem, elem_bt, VecMaskNotUsed) || + !arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad) || + !arch_supports_vector(Op_VectorRearrange, num_elem, elem_bt, VecMaskNotUsed) || + !arch_supports_vector(cast_vopc, num_elem, T_BYTE, VecMaskNotUsed) || + !arch_supports_vector(Op_VectorLoadShuffle, num_elem, index_elem_bt, VecMaskNotUsed) || + !arch_supports_vector(Op_Replicate, num_elem, T_BYTE, VecMaskNotUsed)) { + log_if_needed(" ** not supported: opc=%d vlen=%d etype=%s ismask=useload", + Op_SelectFromTwoVector, num_elem, type2name(elem_bt)); + return false; // not supported + } + lowerSelectFromOp = true; + } + + int cast_vopc = VectorCastNode::opcode(-1, elem_bt, true); + if (!lowerSelectFromOp) { + if (!arch_supports_vector(Op_AndV, num_elem, index_elem_bt, VecMaskNotUsed) || + !arch_supports_vector(Op_Replicate, num_elem, index_elem_bt, VecMaskNotUsed) || + (is_floating_point_type(elem_bt) && + !arch_supports_vector(cast_vopc, num_elem, index_elem_bt, VecMaskNotUsed))) { + log_if_needed(" ** index wrapping not supported: vlen=%d etype=%s" , + num_elem, type2name(elem_bt)); + return false; // not supported + } + } + + ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass(); + const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass); + + Node* opd1 = unbox_vector(argument(3), vbox_type, elem_bt, num_elem); + if (opd1 == nullptr) { + log_if_needed(" ** unbox failed v1=%s", + NodeClassNames[argument(3)->Opcode()]); + return false; + } + Node* opd2 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem); + if (opd2 == nullptr) { + log_if_needed(" ** unbox failed v2=%s", + NodeClassNames[argument(4)->Opcode()]); + return false; + } + Node* opd3 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem); + if (opd3 == nullptr) { + log_if_needed(" ** unbox failed v3=%s", + NodeClassNames[argument(5)->Opcode()]); + return false; + } + + const TypeVect* vt = TypeVect::make(elem_bt, num_elem); + + Node* operation = nullptr; + if (lowerSelectFromOp) { + operation = gvn().transform(LowerSelectFromTwoVectorOperation(gvn(), opd1, opd2, opd3, vt)); + } else { + if (index_elem_bt != elem_bt) { + opd1 = gvn().transform(VectorCastNode::make(cast_vopc, opd1, index_elem_bt, num_elem)); + } + int indexRangeMask = 2 * num_elem - 1; + Node* wrap_mask = gvn().makecon(TypeInteger::make(indexRangeMask, indexRangeMask, Type::WidenMin, index_elem_bt != T_LONG ? T_INT : index_elem_bt)); + Node* wrap_mask_vec = gvn().transform(VectorNode::scalar2vector(wrap_mask, num_elem, Type::get_const_basic_type(index_elem_bt), false)); + opd1 = gvn().transform(VectorNode::make(Op_AndV, opd1, wrap_mask_vec, opd1->bottom_type()->is_vect())); + operation = gvn().transform(VectorNode::make(Op_SelectFromTwoVector, opd1, opd2, opd3, vt)); + } + + // Wrap it up in VectorBox to keep object type information. + Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem); + set_result(vbox); + C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt)))); + return true; +} + // public static // , // M extends VectorMask, diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 094d4dca564..fc1c951cfbd 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -781,6 +781,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeV switch (vopc) { case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt); case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt); + case Op_SelectFromTwoVector: return new SelectFromTwoVectorNode(n1, n2, n3, vt); case Op_SignumVD: return new SignumVDNode(n1, n2, n3, vt); case Op_SignumVF: return new SignumVFNode(n1, n2, n3, vt); default: @@ -2078,6 +2079,7 @@ Node* VectorBlendNode::Identity(PhaseGVN* phase) { return this; } + #ifndef PRODUCT void VectorBoxAllocateNode::dump_spec(outputStream *st) const { CallStaticJavaNode::dump_spec(st); diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index d23e6b8c926..256664983ff 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1612,6 +1612,21 @@ class VectorRearrangeNode : public VectorNode { Node* vec_shuffle() const { return in(2); } }; + +// Select elements from two source vectors based on the wrapped indexes held in +// the first vector. +class SelectFromTwoVectorNode : public VectorNode { +public: + SelectFromTwoVectorNode(Node* indexes, Node* src1, Node* src2, const TypeVect* vt) + : VectorNode(indexes, src1, src2, vt) { + assert(is_integral_type(indexes->bottom_type()->is_vect()->element_basic_type()), + "indexes must be an integral vector"); + } + + virtual int Opcode() const; +}; + + class VectorLoadShuffleNode : public VectorNode { public: VectorLoadShuffleNode(Node* in, const TypeVect* vt) 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 5c4040d9128..63cab418d46 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 @@ -395,6 +395,24 @@ public class VectorSupport { assert isNonCapturingLambda(defaultImpl) : defaultImpl; return defaultImpl.apply(v1, v2, m); } + /* ============================================================================ */ + + public interface SelectFromTwoVector> { + V apply(V v1, V v2, V v3); + } + + @IntrinsicCandidate + public static + , + E> + V selectFromTwoVectorOp(Class vClass, Class eClass, int length, + V v1, V v2, V v3, + SelectFromTwoVector defaultImpl) { + assert isNonCapturingLambda(defaultImpl) : defaultImpl; + return defaultImpl.apply(v1, v2, v3); + } + + /* ============================================================================ */ /* ============================================================================ */ 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 0bc25958a76..3cf25d46f44 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 @@ -506,6 +506,13 @@ final class Byte128Vector extends ByteVector { Byte128Mask.class, (Byte128Mask) m); // specialize } + @Override + @ForceInline + public Byte128Vector selectFrom(Vector v1, + Vector v2) { + return (Byte128Vector) + super.selectFromTemplate((Byte128Vector) v1, (Byte128Vector) v2); // specialize + } @ForceInline @Override 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 639646aa77a..cb9f2679dca 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 @@ -506,6 +506,13 @@ final class Byte256Vector extends ByteVector { Byte256Mask.class, (Byte256Mask) m); // specialize } + @Override + @ForceInline + public Byte256Vector selectFrom(Vector v1, + Vector v2) { + return (Byte256Vector) + super.selectFromTemplate((Byte256Vector) v1, (Byte256Vector) v2); // specialize + } @ForceInline @Override 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 2d8151f6800..f5ff0575703 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 @@ -506,6 +506,13 @@ final class Byte512Vector extends ByteVector { Byte512Mask.class, (Byte512Mask) m); // specialize } + @Override + @ForceInline + public Byte512Vector selectFrom(Vector v1, + Vector v2) { + return (Byte512Vector) + super.selectFromTemplate((Byte512Vector) v1, (Byte512Vector) v2); // specialize + } @ForceInline @Override 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 bc8ed7d704d..37e8978d7e8 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 @@ -506,6 +506,13 @@ final class Byte64Vector extends ByteVector { Byte64Mask.class, (Byte64Mask) m); // specialize } + @Override + @ForceInline + public Byte64Vector selectFrom(Vector v1, + Vector v2) { + return (Byte64Vector) + super.selectFromTemplate((Byte64Vector) v1, (Byte64Vector) v2); // specialize + } @ForceInline @Override 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 597afd8d165..17dcf193ceb 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 @@ -506,6 +506,13 @@ final class ByteMaxVector extends ByteVector { ByteMaxMask.class, (ByteMaxMask) m); // specialize } + @Override + @ForceInline + public ByteMaxVector selectFrom(Vector v1, + Vector v2) { + return (ByteMaxVector) + super.selectFromTemplate((ByteMaxVector) v1, (ByteMaxVector) v2); // specialize + } @ForceInline @Override 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 a23bbc7f709..11c0fda80a4 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 @@ -536,6 +536,19 @@ public abstract class ByteVector extends AbstractVector { return r; } + static ByteVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + byte[] res = new byte[vlen]; + byte[] vecPayload1 = ((ByteVector)indexes).vec(); + byte[] vecPayload2 = ((ByteVector)src1).vec(); + byte[] vecPayload3 = ((ByteVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((ByteVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2575,6 +2588,22 @@ public abstract class ByteVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + ByteVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final ByteVector selectFromTemplate(ByteVector v1, ByteVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), byte.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations /** 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 00840026fff..37607492645 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 @@ -493,6 +493,13 @@ final class Double128Vector extends DoubleVector { Double128Mask.class, (Double128Mask) m); // specialize } + @Override + @ForceInline + public Double128Vector selectFrom(Vector v1, + Vector v2) { + return (Double128Vector) + super.selectFromTemplate((Double128Vector) v1, (Double128Vector) v2); // specialize + } @ForceInline @Override 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 4b42deba738..2e31a802550 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 @@ -493,6 +493,13 @@ final class Double256Vector extends DoubleVector { Double256Mask.class, (Double256Mask) m); // specialize } + @Override + @ForceInline + public Double256Vector selectFrom(Vector v1, + Vector v2) { + return (Double256Vector) + super.selectFromTemplate((Double256Vector) v1, (Double256Vector) v2); // specialize + } @ForceInline @Override 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 c188f990c33..6ed3dd7325c 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 @@ -493,6 +493,13 @@ final class Double512Vector extends DoubleVector { Double512Mask.class, (Double512Mask) m); // specialize } + @Override + @ForceInline + public Double512Vector selectFrom(Vector v1, + Vector v2) { + return (Double512Vector) + super.selectFromTemplate((Double512Vector) v1, (Double512Vector) v2); // specialize + } @ForceInline @Override 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 032fa1ac277..2e1b2135001 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 @@ -493,6 +493,13 @@ final class Double64Vector extends DoubleVector { Double64Mask.class, (Double64Mask) m); // specialize } + @Override + @ForceInline + public Double64Vector selectFrom(Vector v1, + Vector v2) { + return (Double64Vector) + super.selectFromTemplate((Double64Vector) v1, (Double64Vector) v2); // specialize + } @ForceInline @Override 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 7251ec82aa6..8d69b6fcbc7 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 @@ -493,6 +493,13 @@ final class DoubleMaxVector extends DoubleVector { DoubleMaxMask.class, (DoubleMaxMask) m); // specialize } + @Override + @ForceInline + public DoubleMaxVector selectFrom(Vector v1, + Vector v2) { + return (DoubleMaxVector) + super.selectFromTemplate((DoubleMaxVector) v1, (DoubleMaxVector) v2); // specialize + } @ForceInline @Override 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 6cc12048d46..d7fc2cfa97d 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 @@ -525,6 +525,19 @@ public abstract class DoubleVector extends AbstractVector { return r; } + static DoubleVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + double[] res = new double[vlen]; + double[] vecPayload1 = ((DoubleVector)indexes).vec(); + double[] vecPayload2 = ((DoubleVector)src1).vec(); + double[] vecPayload3 = ((DoubleVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((DoubleVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2417,6 +2430,22 @@ public abstract class DoubleVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + DoubleVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final DoubleVector selectFromTemplate(DoubleVector v1, DoubleVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), double.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations 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 2e016725f81..79239532cc6 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 @@ -493,6 +493,13 @@ final class Float128Vector extends FloatVector { Float128Mask.class, (Float128Mask) m); // specialize } + @Override + @ForceInline + public Float128Vector selectFrom(Vector v1, + Vector v2) { + return (Float128Vector) + super.selectFromTemplate((Float128Vector) v1, (Float128Vector) v2); // specialize + } @ForceInline @Override 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 00e60835883..5f5a26fd316 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 @@ -493,6 +493,13 @@ final class Float256Vector extends FloatVector { Float256Mask.class, (Float256Mask) m); // specialize } + @Override + @ForceInline + public Float256Vector selectFrom(Vector v1, + Vector v2) { + return (Float256Vector) + super.selectFromTemplate((Float256Vector) v1, (Float256Vector) v2); // specialize + } @ForceInline @Override 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 1f2a792c52c..f8c191ea016 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 @@ -493,6 +493,13 @@ final class Float512Vector extends FloatVector { Float512Mask.class, (Float512Mask) m); // specialize } + @Override + @ForceInline + public Float512Vector selectFrom(Vector v1, + Vector v2) { + return (Float512Vector) + super.selectFromTemplate((Float512Vector) v1, (Float512Vector) v2); // specialize + } @ForceInline @Override 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 6c913ce84a9..9496e598868 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 @@ -493,6 +493,13 @@ final class Float64Vector extends FloatVector { Float64Mask.class, (Float64Mask) m); // specialize } + @Override + @ForceInline + public Float64Vector selectFrom(Vector v1, + Vector v2) { + return (Float64Vector) + super.selectFromTemplate((Float64Vector) v1, (Float64Vector) v2); // specialize + } @ForceInline @Override 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 b9a0a93f912..6f093957262 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 @@ -493,6 +493,13 @@ final class FloatMaxVector extends FloatVector { FloatMaxMask.class, (FloatMaxMask) m); // specialize } + @Override + @ForceInline + public FloatMaxVector selectFrom(Vector v1, + Vector v2) { + return (FloatMaxVector) + super.selectFromTemplate((FloatMaxVector) v1, (FloatMaxVector) v2); // specialize + } @ForceInline @Override 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 b962dc55ce3..098eed06095 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 @@ -525,6 +525,19 @@ public abstract class FloatVector extends AbstractVector { return r; } + static FloatVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + float[] res = new float[vlen]; + float[] vecPayload1 = ((FloatVector)indexes).vec(); + float[] vecPayload2 = ((FloatVector)src1).vec(); + float[] vecPayload3 = ((FloatVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((FloatVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2429,6 +2442,22 @@ public abstract class FloatVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + FloatVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final FloatVector selectFromTemplate(FloatVector v1, FloatVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), float.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations 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 f7135e19cb6..4aa1e8044b0 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 @@ -506,6 +506,13 @@ final class Int128Vector extends IntVector { Int128Mask.class, (Int128Mask) m); // specialize } + @Override + @ForceInline + public Int128Vector selectFrom(Vector v1, + Vector v2) { + return (Int128Vector) + super.selectFromTemplate((Int128Vector) v1, (Int128Vector) v2); // specialize + } @ForceInline @Override 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 474ff974b31..753f96f216f 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 @@ -506,6 +506,13 @@ final class Int256Vector extends IntVector { Int256Mask.class, (Int256Mask) m); // specialize } + @Override + @ForceInline + public Int256Vector selectFrom(Vector v1, + Vector v2) { + return (Int256Vector) + super.selectFromTemplate((Int256Vector) v1, (Int256Vector) v2); // specialize + } @ForceInline @Override 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 9fec8c0c99f..8e6ed6fc882 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 @@ -506,6 +506,13 @@ final class Int512Vector extends IntVector { Int512Mask.class, (Int512Mask) m); // specialize } + @Override + @ForceInline + public Int512Vector selectFrom(Vector v1, + Vector v2) { + return (Int512Vector) + super.selectFromTemplate((Int512Vector) v1, (Int512Vector) v2); // specialize + } @ForceInline @Override 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 3b3c0723ee1..98cd39d9beb 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 @@ -506,6 +506,13 @@ final class Int64Vector extends IntVector { Int64Mask.class, (Int64Mask) m); // specialize } + @Override + @ForceInline + public Int64Vector selectFrom(Vector v1, + Vector v2) { + return (Int64Vector) + super.selectFromTemplate((Int64Vector) v1, (Int64Vector) v2); // specialize + } @ForceInline @Override 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 5738cb7a4bc..f301161b980 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 @@ -506,6 +506,13 @@ final class IntMaxVector extends IntVector { IntMaxMask.class, (IntMaxMask) m); // specialize } + @Override + @ForceInline + public IntMaxVector selectFrom(Vector v1, + Vector v2) { + return (IntMaxVector) + super.selectFromTemplate((IntMaxVector) v1, (IntMaxVector) v2); // specialize + } @ForceInline @Override 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 16b5ceecba3..b61e2fc991e 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 @@ -536,6 +536,19 @@ public abstract class IntVector extends AbstractVector { return r; } + static IntVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + int[] res = new int[vlen]; + int[] vecPayload1 = ((IntVector)indexes).vec(); + int[] vecPayload2 = ((IntVector)src1).vec(); + int[] vecPayload3 = ((IntVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((IntVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2560,6 +2573,22 @@ public abstract class IntVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + IntVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final IntVector selectFromTemplate(IntVector v1, IntVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), int.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations /** 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 567789627c6..c65816a4d6c 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 @@ -496,6 +496,13 @@ final class Long128Vector extends LongVector { Long128Mask.class, (Long128Mask) m); // specialize } + @Override + @ForceInline + public Long128Vector selectFrom(Vector v1, + Vector v2) { + return (Long128Vector) + super.selectFromTemplate((Long128Vector) v1, (Long128Vector) v2); // specialize + } @ForceInline @Override 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 5ef0f121464..7ca3e43e92b 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 @@ -496,6 +496,13 @@ final class Long256Vector extends LongVector { Long256Mask.class, (Long256Mask) m); // specialize } + @Override + @ForceInline + public Long256Vector selectFrom(Vector v1, + Vector v2) { + return (Long256Vector) + super.selectFromTemplate((Long256Vector) v1, (Long256Vector) v2); // specialize + } @ForceInline @Override 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 acdb471609f..317cac1f110 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 @@ -496,6 +496,13 @@ final class Long512Vector extends LongVector { Long512Mask.class, (Long512Mask) m); // specialize } + @Override + @ForceInline + public Long512Vector selectFrom(Vector v1, + Vector v2) { + return (Long512Vector) + super.selectFromTemplate((Long512Vector) v1, (Long512Vector) v2); // specialize + } @ForceInline @Override 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 627f7437367..b13712595db 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 @@ -496,6 +496,13 @@ final class Long64Vector extends LongVector { Long64Mask.class, (Long64Mask) m); // specialize } + @Override + @ForceInline + public Long64Vector selectFrom(Vector v1, + Vector v2) { + return (Long64Vector) + super.selectFromTemplate((Long64Vector) v1, (Long64Vector) v2); // specialize + } @ForceInline @Override 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 aec3bb89fcd..9edc442be88 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 @@ -496,6 +496,13 @@ final class LongMaxVector extends LongVector { LongMaxMask.class, (LongMaxMask) m); // specialize } + @Override + @ForceInline + public LongMaxVector selectFrom(Vector v1, + Vector v2) { + return (LongMaxVector) + super.selectFromTemplate((LongMaxVector) v1, (LongMaxVector) v2); // specialize + } @ForceInline @Override 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 15ac2bc7b7f..68166bd9852 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 @@ -536,6 +536,19 @@ public abstract class LongVector extends AbstractVector { return r; } + static LongVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + long[] res = new long[vlen]; + long[] vecPayload1 = ((LongVector)indexes).vec(); + long[] vecPayload2 = ((LongVector)src1).vec(); + long[] vecPayload3 = ((LongVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((LongVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2426,6 +2439,22 @@ public abstract class LongVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + LongVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final LongVector selectFromTemplate(LongVector v1, LongVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), long.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations /** 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 fe34886512a..b013e4b2825 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 @@ -506,6 +506,13 @@ final class Short128Vector extends ShortVector { Short128Mask.class, (Short128Mask) m); // specialize } + @Override + @ForceInline + public Short128Vector selectFrom(Vector v1, + Vector v2) { + return (Short128Vector) + super.selectFromTemplate((Short128Vector) v1, (Short128Vector) v2); // specialize + } @ForceInline @Override 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 243e24ad26b..af4c862eaf3 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 @@ -506,6 +506,13 @@ final class Short256Vector extends ShortVector { Short256Mask.class, (Short256Mask) m); // specialize } + @Override + @ForceInline + public Short256Vector selectFrom(Vector v1, + Vector v2) { + return (Short256Vector) + super.selectFromTemplate((Short256Vector) v1, (Short256Vector) v2); // specialize + } @ForceInline @Override 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 41147836089..3bb019f3b7c 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 @@ -506,6 +506,13 @@ final class Short512Vector extends ShortVector { Short512Mask.class, (Short512Mask) m); // specialize } + @Override + @ForceInline + public Short512Vector selectFrom(Vector v1, + Vector v2) { + return (Short512Vector) + super.selectFromTemplate((Short512Vector) v1, (Short512Vector) v2); // specialize + } @ForceInline @Override 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 d80d4c4e2ec..905e313e95c 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 @@ -506,6 +506,13 @@ final class Short64Vector extends ShortVector { Short64Mask.class, (Short64Mask) m); // specialize } + @Override + @ForceInline + public Short64Vector selectFrom(Vector v1, + Vector v2) { + return (Short64Vector) + super.selectFromTemplate((Short64Vector) v1, (Short64Vector) v2); // specialize + } @ForceInline @Override 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 799483a6675..5bb1beee6ed 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 @@ -506,6 +506,13 @@ final class ShortMaxVector extends ShortVector { ShortMaxMask.class, (ShortMaxMask) m); // specialize } + @Override + @ForceInline + public ShortMaxVector selectFrom(Vector v1, + Vector v2) { + return (ShortMaxVector) + super.selectFromTemplate((ShortMaxVector) v1, (ShortMaxVector) v2); // specialize + } @ForceInline @Override 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 fb0512fd5b9..2f1ea210b90 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 @@ -536,6 +536,19 @@ public abstract class ShortVector extends AbstractVector { return r; } + static ShortVector selectFromTwoVectorHelper(Vector indexes, Vector src1, Vector src2) { + int vlen = indexes.length(); + short[] res = new short[vlen]; + short[] vecPayload1 = ((ShortVector)indexes).vec(); + short[] vecPayload2 = ((ShortVector)src1).vec(); + short[] vecPayload3 = ((ShortVector)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return ((ShortVector)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2576,6 +2589,22 @@ public abstract class ShortVector extends AbstractVector { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + ShortVector selectFrom(Vector v1, Vector v2); + + + /*package-private*/ + @ForceInline + final ShortVector selectFromTemplate(ShortVector v1, ShortVector v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), short.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations /** 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 fda073f6863..5b6dd3d09ac 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 @@ -2756,6 +2756,61 @@ public abstract class Vector extends jdk.internal.vm.vector.VectorSupport.Vec */ public abstract Vector selectFrom(Vector v); + /** + * Using values stored in the lanes of this vector, + * assemble values stored in the second vector {@code v1} + * and third vector {@code v2}. The second and third vectors thus + * serve as a table, whose elements are selected by indexes + * in this vector. + * + * This is a cross-lane operation that rearranges the lane + * elements of the argument vectors, under the control of + * this vector. + * + * For each lane {@code N} of this vector, and for each lane + * value {@code I=wrapIndex(this.lane(N)} in this vector, + * the output lane {@code N} obtains the value from + * the second vector at lane {@code I} if {@code I < VLENGTH}. + * Otherwise, the output lane {@code N} obtains the value from + * the third vector at lane {@code I - VLENGTH}. + * + * Here, {@code VLENGTH} is the result of {@code this.length()}, + * and for integral values {@code wrapIndex} computes the result of + * {@code Math.floorMod(E, 2 * VLENGTH)}, where {@code E} is the index + * to be wrapped. As long as {@code VLENGTH} is a power of two, then the + * result is also equal to {@code E & (2 * VLENGTH - 1)}. + * + * For floating point values {@code wrapIndex} computes + * {@code Math.floorMod(convert(E), 2 * VLENGTH)}, where {@code convert} + * converts the floating point value to an integral value with the same + * number of representational bits - as in converting a double value to + * a long value ({@code (long)doubleVal}), or a float value to an int value + * ({@code (int)floatVal}). + * + * In this way, the result contains only values stored in the + * argument vectors {@code v1} and {@code v2}, but presented in + * an order which depends on the index values in {@code this}. + * + * The result for integral values is the same as the expression + * {@snippet lang=java : + * v1.rearrange( + * this.lanewise(VectorOperators.AND, 2 * VLENGTH - 1).toShuffle(), + * v2) + * } + * when {@code VLENGTH} is a power of two. + * The lane-wise {@code AND} operation results in a vector whose + * elements are in the range {@code [0, 2 * VLENGTH - 1])}. The shuffle + * conversion results in a partially wrapped shuffle whose indexes are + * in the range {@code [-VLENGTH, VLENGTH - 1])}, where exceptional + * indexes are used to select elements in the third vector. + * + * @param v1 the first input vector + * @param v2 the second input vector + * @return the rearrangement of lane elements of {@code v1} and {@code v2} + * @see #rearrange(VectorShuffle,Vector) + */ + public abstract Vector selectFrom(Vector v1, Vector v2); + /** * Using index values stored in the lanes of this vector, * assemble values stored in second vector, under the control 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 507fe84bfba..38c4b1c94fe 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 @@ -563,6 +563,7 @@ public abstract class VectorOperators { public static final /*bitwise*/ Associative OR = assoc("OR", "|", VectorSupport.VECTOR_OP_OR, VO_NOFP+VO_ASSOC); /*package-private*/ /** Version of OR which works on float and double too. */ static final Associative OR_UNCHECKED = assoc("OR_UNCHECKED", "|", VectorSupport.VECTOR_OP_OR, VO_ASSOC+VO_PRIVATE); + /** Produce {@code a^b}. Integral only. */ public static final /*bitwise*/ Associative XOR = assoc("XOR", "^", VectorSupport.VECTOR_OP_XOR, VO_NOFP+VO_ASSOC); 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 fcc128ea8c7..b9a48005ccf 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 @@ -550,6 +550,19 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { return r; } + static $abstractvectortype$ selectFromTwoVectorHelper(Vector<$Boxtype$> indexes, Vector<$Boxtype$> src1, Vector<$Boxtype$> src2) { + int vlen = indexes.length(); + $type$[] res = new $type$[vlen]; + $type$[] vecPayload1 = (($abstractvectortype$)indexes).vec(); + $type$[] vecPayload2 = (($abstractvectortype$)src1).vec(); + $type$[] vecPayload3 = (($abstractvectortype$)src2).vec(); + for (int i = 0; i < vlen; i++) { + int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen); + res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index]; + } + return (($abstractvectortype$)src1).vectorFactory(res); + } + // Static factories (other than memory operations) // Note: A surprising behavior in javadoc @@ -2952,6 +2965,22 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { v2.rearrange(v1.toShuffle(), _m)); } + + /** + * {@inheritDoc} + */ + @Override + public abstract + $abstractvectortype$ selectFrom(Vector<$Boxtype$> v1, Vector<$Boxtype$> v2); + + + /*package-private*/ + @ForceInline + final $abstractvectortype$ selectFromTemplate($abstractvectortype$ v1, $abstractvectortype$ v2) { + return VectorSupport.selectFromTwoVectorOp(getClass(), $type$.class, length(), this, v1, v2, + (vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)); + } + /// Ternary operations #if[BITWISE] 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 483962b4e06..9752a795ea7 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 @@ -512,6 +512,13 @@ final class $vectortype$ extends $abstractvectortype$ { $masktype$.class, ($masktype$) m); // specialize } + @Override + @ForceInline + public $vectortype$ selectFrom(Vector<$Boxtype$> v1, + Vector<$Boxtype$> v2) { + return ($vectortype$) + super.selectFromTemplate(($vectortype$) v1, ($vectortype$) v2); // specialize + } #if[FP] @ForceInline diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java index 77d0dd20974..eda803b3f35 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java @@ -302,6 +302,25 @@ public class Byte128VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) { int i = 0, j = 0; try { @@ -962,6 +981,18 @@ public class Byte128VectorTests extends AbstractVectorTest { flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("byte[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(RAND.nextInt())); + }) + ); + + static final List>> BYTE_GENERATOR_SELECT_FROM_TRIPLES = + BYTE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] byteBinaryOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -989,6 +1020,12 @@ public class Byte128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSelectFromTwoVectorOpProvider() { + return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] byteTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5746,6 +5783,24 @@ public class Byte128VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "byteSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorByte128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] idx = fc.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "byteUnaryOpSelectFromMaskProvider") static void SelectFromByte128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java index 31e38f633ff..06cc13c0b12 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java @@ -302,6 +302,25 @@ public class Byte256VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) { int i = 0, j = 0; try { @@ -962,6 +981,18 @@ public class Byte256VectorTests extends AbstractVectorTest { flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("byte[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(RAND.nextInt())); + }) + ); + + static final List>> BYTE_GENERATOR_SELECT_FROM_TRIPLES = + BYTE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] byteBinaryOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -989,6 +1020,12 @@ public class Byte256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSelectFromTwoVectorOpProvider() { + return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] byteTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5746,6 +5783,24 @@ public class Byte256VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "byteSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorByte256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] idx = fc.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "byteUnaryOpSelectFromMaskProvider") static void SelectFromByte256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java index 9204c3ed1ad..a75aa42ef20 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java @@ -302,6 +302,25 @@ public class Byte512VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) { int i = 0, j = 0; try { @@ -962,6 +981,18 @@ public class Byte512VectorTests extends AbstractVectorTest { flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("byte[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(RAND.nextInt())); + }) + ); + + static final List>> BYTE_GENERATOR_SELECT_FROM_TRIPLES = + BYTE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] byteBinaryOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -989,6 +1020,12 @@ public class Byte512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSelectFromTwoVectorOpProvider() { + return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] byteTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5746,6 +5783,24 @@ public class Byte512VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "byteSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorByte512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] idx = fc.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "byteUnaryOpSelectFromMaskProvider") static void SelectFromByte512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java index 9af640a3133..b621c28a779 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java @@ -302,6 +302,25 @@ public class Byte64VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) { int i = 0, j = 0; try { @@ -962,6 +981,18 @@ public class Byte64VectorTests extends AbstractVectorTest { flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("byte[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(RAND.nextInt())); + }) + ); + + static final List>> BYTE_GENERATOR_SELECT_FROM_TRIPLES = + BYTE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] byteBinaryOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -989,6 +1020,12 @@ public class Byte64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSelectFromTwoVectorOpProvider() { + return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] byteTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5746,6 +5783,24 @@ public class Byte64VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "byteSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorByte64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] idx = fc.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "byteUnaryOpSelectFromMaskProvider") static void SelectFromByte64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java index 1c0d5362b53..bbd354c958a 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java @@ -307,6 +307,25 @@ public class ByteMaxVectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) { int i = 0, j = 0; try { @@ -967,6 +986,18 @@ public class ByteMaxVectorTests extends AbstractVectorTest { flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("byte[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(RAND.nextInt())); + }) + ); + + static final List>> BYTE_GENERATOR_SELECT_FROM_TRIPLES = + BYTE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] byteBinaryOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -994,6 +1025,12 @@ public class ByteMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSelectFromTwoVectorOpProvider() { + return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] byteTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5751,6 +5788,24 @@ public class ByteMaxVectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "byteSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorByteMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] idx = fc.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "byteUnaryOpSelectFromMaskProvider") static void SelectFromByteMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java index 4efeb8f2059..05678c4290b 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) { int i = 0, j = 0; try { @@ -1108,6 +1127,18 @@ relativeError)); flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("double[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(RAND.nextInt())); + }) + ); + + static final List>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES = + DOUBLE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] doubleBinaryOpProvider() { return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1135,6 +1166,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] doubleSelectFromTwoVectorOpProvider() { + return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] doubleTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4799,6 +4836,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorDouble128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + double[] a = fa.apply(SPECIES.length()); + double[] b = fb.apply(SPECIES.length()); + double[] idx = fc.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i); + DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider") static void SelectFromDouble128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java index 04b0e7dc0d6..fe59fc85a2e 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) { int i = 0, j = 0; try { @@ -1108,6 +1127,18 @@ relativeError)); flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("double[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(RAND.nextInt())); + }) + ); + + static final List>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES = + DOUBLE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] doubleBinaryOpProvider() { return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1135,6 +1166,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] doubleSelectFromTwoVectorOpProvider() { + return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] doubleTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4799,6 +4836,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorDouble256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + double[] a = fa.apply(SPECIES.length()); + double[] b = fb.apply(SPECIES.length()); + double[] idx = fc.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i); + DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider") static void SelectFromDouble256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java index ad03b8b5c7b..1e5b68ab989 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) { int i = 0, j = 0; try { @@ -1108,6 +1127,18 @@ relativeError)); flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("double[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(RAND.nextInt())); + }) + ); + + static final List>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES = + DOUBLE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] doubleBinaryOpProvider() { return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1135,6 +1166,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] doubleSelectFromTwoVectorOpProvider() { + return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] doubleTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4799,6 +4836,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorDouble512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + double[] a = fa.apply(SPECIES.length()); + double[] b = fb.apply(SPECIES.length()); + double[] idx = fc.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i); + DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider") static void SelectFromDouble512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java index 9321215c3de..b56b4d237f4 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) { int i = 0, j = 0; try { @@ -1108,6 +1127,18 @@ relativeError)); flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("double[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(RAND.nextInt())); + }) + ); + + static final List>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES = + DOUBLE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] doubleBinaryOpProvider() { return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1135,6 +1166,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] doubleSelectFromTwoVectorOpProvider() { + return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] doubleTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4799,6 +4836,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorDouble64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + double[] a = fa.apply(SPECIES.length()); + double[] b = fb.apply(SPECIES.length()); + double[] idx = fc.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i); + DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider") static void SelectFromDouble64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java index a6b80376196..43da4f57636 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java @@ -326,6 +326,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) { int i = 0, j = 0; try { @@ -1113,6 +1132,18 @@ relativeError)); flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("double[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (double)(RAND.nextInt())); + }) + ); + + static final List>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES = + DOUBLE_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] doubleBinaryOpProvider() { return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1140,6 +1171,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] doubleSelectFromTwoVectorOpProvider() { + return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] doubleTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4804,6 +4841,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorDoubleMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + double[] a = fa.apply(SPECIES.length()); + double[] b = fb.apply(SPECIES.length()); + double[] idx = fc.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i); + DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider") static void SelectFromDoubleMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java index 6bad9098544..549199513d5 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) { int i = 0, j = 0; try { @@ -1119,6 +1138,18 @@ relativeError)); flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("float[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(RAND.nextInt())); + }) + ); + + static final List>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES = + FLOAT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] floatBinaryOpProvider() { return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1146,6 +1177,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] floatSelectFromTwoVectorOpProvider() { + return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] floatTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4778,6 +4815,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "floatSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorFloat128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + float[] a = fa.apply(SPECIES.length()); + float[] b = fb.apply(SPECIES.length()); + float[] idx = fc.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + FloatVector bv = FloatVector.fromArray(SPECIES, b, i); + FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "floatUnaryOpSelectFromMaskProvider") static void SelectFromFloat128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java index e714ace5a78..6d17727c325 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) { int i = 0, j = 0; try { @@ -1119,6 +1138,18 @@ relativeError)); flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("float[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(RAND.nextInt())); + }) + ); + + static final List>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES = + FLOAT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] floatBinaryOpProvider() { return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1146,6 +1177,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] floatSelectFromTwoVectorOpProvider() { + return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] floatTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4778,6 +4815,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "floatSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorFloat256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + float[] a = fa.apply(SPECIES.length()); + float[] b = fb.apply(SPECIES.length()); + float[] idx = fc.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + FloatVector bv = FloatVector.fromArray(SPECIES, b, i); + FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "floatUnaryOpSelectFromMaskProvider") static void SelectFromFloat256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java index f3c5a316c79..c2290eb7080 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) { int i = 0, j = 0; try { @@ -1119,6 +1138,18 @@ relativeError)); flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("float[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(RAND.nextInt())); + }) + ); + + static final List>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES = + FLOAT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] floatBinaryOpProvider() { return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1146,6 +1177,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] floatSelectFromTwoVectorOpProvider() { + return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] floatTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4778,6 +4815,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "floatSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorFloat512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + float[] a = fa.apply(SPECIES.length()); + float[] b = fb.apply(SPECIES.length()); + float[] idx = fc.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + FloatVector bv = FloatVector.fromArray(SPECIES, b, i); + FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "floatUnaryOpSelectFromMaskProvider") static void SelectFromFloat512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java index 378c2ae783f..0d50726f644 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java @@ -321,6 +321,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) { int i = 0, j = 0; try { @@ -1119,6 +1138,18 @@ relativeError)); flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("float[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(RAND.nextInt())); + }) + ); + + static final List>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES = + FLOAT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] floatBinaryOpProvider() { return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1146,6 +1177,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] floatSelectFromTwoVectorOpProvider() { + return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] floatTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4778,6 +4815,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "floatSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorFloat64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + float[] a = fa.apply(SPECIES.length()); + float[] b = fb.apply(SPECIES.length()); + float[] idx = fc.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + FloatVector bv = FloatVector.fromArray(SPECIES, b, i); + FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "floatUnaryOpSelectFromMaskProvider") static void SelectFromFloat64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java index a2dc38413ec..6a0b1301ab3 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java @@ -326,6 +326,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) { int i = 0, j = 0; try { @@ -1124,6 +1143,18 @@ relativeError)); flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("float[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (float)(RAND.nextInt())); + }) + ); + + static final List>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES = + FLOAT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] floatBinaryOpProvider() { return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1151,6 +1182,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] floatSelectFromTwoVectorOpProvider() { + return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] floatTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -4783,6 +4820,24 @@ relativeError)); assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "floatSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorFloatMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + float[] a = fa.apply(SPECIES.length()); + float[] b = fb.apply(SPECIES.length()); + float[] idx = fc.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + FloatVector bv = FloatVector.fromArray(SPECIES, b, i); + FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "floatUnaryOpSelectFromMaskProvider") static void SelectFromFloatMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java index 1ee0bbc3197..528d26a952b 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java @@ -302,6 +302,25 @@ public class Int128VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Int128VectorTests extends AbstractVectorTest { flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("int[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(RAND.nextInt())); + }) + ); + + static final List>> INT_GENERATOR_SELECT_FROM_TRIPLES = + INT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] intBinaryOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Int128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSelectFromTwoVectorOpProvider() { + return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] intTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5779,6 +5816,24 @@ public class Int128VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "intSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorInt128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] idx = fc.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector idxv = IntVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "intUnaryOpShuffleMaskProvider") static void SelectFromInt128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java index 5257af21c94..09561e0f3c4 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java @@ -302,6 +302,25 @@ public class Int256VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Int256VectorTests extends AbstractVectorTest { flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("int[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(RAND.nextInt())); + }) + ); + + static final List>> INT_GENERATOR_SELECT_FROM_TRIPLES = + INT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] intBinaryOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Int256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSelectFromTwoVectorOpProvider() { + return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] intTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5779,6 +5816,24 @@ public class Int256VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "intSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorInt256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] idx = fc.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector idxv = IntVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "intUnaryOpShuffleMaskProvider") static void SelectFromInt256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java index 6d4633cc7ae..e6d1aa68f56 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java @@ -302,6 +302,25 @@ public class Int512VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Int512VectorTests extends AbstractVectorTest { flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("int[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(RAND.nextInt())); + }) + ); + + static final List>> INT_GENERATOR_SELECT_FROM_TRIPLES = + INT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] intBinaryOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Int512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSelectFromTwoVectorOpProvider() { + return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] intTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5779,6 +5816,24 @@ public class Int512VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "intSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorInt512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] idx = fc.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector idxv = IntVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "intUnaryOpShuffleMaskProvider") static void SelectFromInt512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java index 7bd1543ed5c..4435d31cd04 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java @@ -302,6 +302,25 @@ public class Int64VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Int64VectorTests extends AbstractVectorTest { flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("int[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(RAND.nextInt())); + }) + ); + + static final List>> INT_GENERATOR_SELECT_FROM_TRIPLES = + INT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] intBinaryOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Int64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSelectFromTwoVectorOpProvider() { + return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] intTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5779,6 +5816,24 @@ public class Int64VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "intSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorInt64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] idx = fc.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector idxv = IntVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "intUnaryOpShuffleMaskProvider") static void SelectFromInt64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java index 71d1ce594f9..94dce66d951 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java @@ -307,6 +307,25 @@ public class IntMaxVectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) { int i = 0, j = 0; try { @@ -957,6 +976,18 @@ public class IntMaxVectorTests extends AbstractVectorTest { flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("int[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(RAND.nextInt())); + }) + ); + + static final List>> INT_GENERATOR_SELECT_FROM_TRIPLES = + INT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] intBinaryOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -984,6 +1015,12 @@ public class IntMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSelectFromTwoVectorOpProvider() { + return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] intTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5784,6 +5821,24 @@ public class IntMaxVectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "intSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorIntMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] idx = fc.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector idxv = IntVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "intUnaryOpShuffleMaskProvider") static void SelectFromIntMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java index bcec2dee9fe..7e6bf6b7b81 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java @@ -259,6 +259,25 @@ public class Long128VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) { int i = 0, j = 0; try { @@ -942,6 +961,18 @@ public class Long128VectorTests extends AbstractVectorTest { flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("long[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(RAND.nextInt())); + }) + ); + + static final List>> LONG_GENERATOR_SELECT_FROM_TRIPLES = + LONG_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] longBinaryOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -969,6 +1000,12 @@ public class Long128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSelectFromTwoVectorOpProvider() { + return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] longTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5665,6 +5702,24 @@ public class Long128VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "longSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorLong128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] idx = fc.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector idxv = LongVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "longUnaryOpSelectFromMaskProvider") static void SelectFromLong128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java index e8f2fb1301c..299b7007ba5 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java @@ -259,6 +259,25 @@ public class Long256VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) { int i = 0, j = 0; try { @@ -942,6 +961,18 @@ public class Long256VectorTests extends AbstractVectorTest { flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("long[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(RAND.nextInt())); + }) + ); + + static final List>> LONG_GENERATOR_SELECT_FROM_TRIPLES = + LONG_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] longBinaryOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -969,6 +1000,12 @@ public class Long256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSelectFromTwoVectorOpProvider() { + return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] longTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5665,6 +5702,24 @@ public class Long256VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "longSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorLong256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] idx = fc.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector idxv = LongVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "longUnaryOpSelectFromMaskProvider") static void SelectFromLong256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java index 022f1490fcc..e6eafa02ed0 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java @@ -259,6 +259,25 @@ public class Long512VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) { int i = 0, j = 0; try { @@ -942,6 +961,18 @@ public class Long512VectorTests extends AbstractVectorTest { flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("long[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(RAND.nextInt())); + }) + ); + + static final List>> LONG_GENERATOR_SELECT_FROM_TRIPLES = + LONG_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] longBinaryOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -969,6 +1000,12 @@ public class Long512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSelectFromTwoVectorOpProvider() { + return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] longTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5665,6 +5702,24 @@ public class Long512VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "longSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorLong512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] idx = fc.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector idxv = LongVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "longUnaryOpSelectFromMaskProvider") static void SelectFromLong512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java index fe886bf93d8..035db048eb8 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java @@ -259,6 +259,25 @@ public class Long64VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) { int i = 0, j = 0; try { @@ -942,6 +961,18 @@ public class Long64VectorTests extends AbstractVectorTest { flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("long[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(RAND.nextInt())); + }) + ); + + static final List>> LONG_GENERATOR_SELECT_FROM_TRIPLES = + LONG_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] longBinaryOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -969,6 +1000,12 @@ public class Long64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSelectFromTwoVectorOpProvider() { + return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] longTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5665,6 +5702,24 @@ public class Long64VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "longSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorLong64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] idx = fc.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector idxv = LongVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "longUnaryOpSelectFromMaskProvider") static void SelectFromLong64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java index b77d6eeb118..68ea78db4f0 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java @@ -264,6 +264,25 @@ public class LongMaxVectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) { int i = 0, j = 0; try { @@ -947,6 +966,18 @@ public class LongMaxVectorTests extends AbstractVectorTest { flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("long[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(RAND.nextInt())); + }) + ); + + static final List>> LONG_GENERATOR_SELECT_FROM_TRIPLES = + LONG_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] longBinaryOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -974,6 +1005,12 @@ public class LongMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSelectFromTwoVectorOpProvider() { + return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] longTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5670,6 +5707,24 @@ public class LongMaxVectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "longSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorLongMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] idx = fc.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector idxv = LongVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "longUnaryOpSelectFromMaskProvider") static void SelectFromLongMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java index 2a82ada044e..2103be0994c 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java @@ -302,6 +302,25 @@ public class Short128VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Short128VectorTests extends AbstractVectorTest { flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("short[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(RAND.nextInt())); + }) + ); + + static final List>> SHORT_GENERATOR_SELECT_FROM_TRIPLES = + SHORT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] shortBinaryOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Short128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSelectFromTwoVectorOpProvider() { + return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] shortTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5726,6 +5763,24 @@ public class Short128VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "shortSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorShort128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] idx = fc.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "shortUnaryOpSelectFromMaskProvider") static void SelectFromShort128VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java index 69a8432acef..feed6bbe5f3 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java @@ -302,6 +302,25 @@ public class Short256VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Short256VectorTests extends AbstractVectorTest { flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("short[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(RAND.nextInt())); + }) + ); + + static final List>> SHORT_GENERATOR_SELECT_FROM_TRIPLES = + SHORT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] shortBinaryOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Short256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSelectFromTwoVectorOpProvider() { + return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] shortTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5726,6 +5763,24 @@ public class Short256VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "shortSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorShort256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] idx = fc.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "shortUnaryOpSelectFromMaskProvider") static void SelectFromShort256VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java index 8e892a8a48e..a1a1ac6bc37 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java @@ -302,6 +302,25 @@ public class Short512VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Short512VectorTests extends AbstractVectorTest { flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("short[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(RAND.nextInt())); + }) + ); + + static final List>> SHORT_GENERATOR_SELECT_FROM_TRIPLES = + SHORT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] shortBinaryOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Short512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSelectFromTwoVectorOpProvider() { + return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] shortTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5726,6 +5763,24 @@ public class Short512VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "shortSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorShort512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] idx = fc.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "shortUnaryOpSelectFromMaskProvider") static void SelectFromShort512VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java index 97658d4257d..cc14cccd119 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java @@ -302,6 +302,25 @@ public class Short64VectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) { int i = 0, j = 0; try { @@ -952,6 +971,18 @@ public class Short64VectorTests extends AbstractVectorTest { flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("short[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(RAND.nextInt())); + }) + ); + + static final List>> SHORT_GENERATOR_SELECT_FROM_TRIPLES = + SHORT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] shortBinaryOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -979,6 +1010,12 @@ public class Short64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSelectFromTwoVectorOpProvider() { + return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] shortTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5726,6 +5763,24 @@ public class Short64VectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "shortSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorShort64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] idx = fc.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "shortUnaryOpSelectFromMaskProvider") static void SelectFromShort64VectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java index 0857c13ef3c..a557494f74c 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java @@ -307,6 +307,25 @@ public class ShortMaxVectorTests extends AbstractVectorTest { } } + static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) { int i = 0, j = 0; try { @@ -957,6 +976,18 @@ public class ShortMaxVectorTests extends AbstractVectorTest { flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("short[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(RAND.nextInt())); + }) + ); + + static final List>> SHORT_GENERATOR_SELECT_FROM_TRIPLES = + SHORT_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] shortBinaryOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -984,6 +1015,12 @@ public class ShortMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSelectFromTwoVectorOpProvider() { + return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] shortTernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). @@ -5731,6 +5768,24 @@ public class ShortMaxVectorTests extends AbstractVectorTest { assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "shortSelectFromTwoVectorOpProvider") + static void SelectFromTwoVectorShortMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] idx = fc.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + @Test(dataProvider = "shortUnaryOpSelectFromMaskProvider") static void SelectFromShortMaxVectorTestsMaskedSmokeTest(IntFunction fa, BiFunction fs, diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template b/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template index 0d3b310f60f..9a020c66d52 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Miscellaneous.template @@ -297,6 +297,24 @@ assertSelectFromArraysEquals(r, a, order, SPECIES.length()); } + @Test(dataProvider = "$type$SelectFromTwoVectorOpProvider") + static void SelectFromTwoVector$vectorteststype$(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb, IntFunction<$type$[]> fc) { + $type$[] a = fa.apply(SPECIES.length()); + $type$[] b = fb.apply(SPECIES.length()); + $type$[] idx = fc.apply(SPECIES.length()); + $type$[] r = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < idx.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); + $abstractvectortype$ bv = $abstractvectortype$.fromArray(SPECIES, b, i); + $abstractvectortype$ idxv = $abstractvectortype$.fromArray(SPECIES, idx, i); + idxv.selectFrom(av, bv).intoArray(r, i); + } + } + assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length()); + } + #if[Int] @Test(dataProvider = "$type$UnaryOpShuffleMaskProvider") #else[Int] diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template index 42440881771..2f33ede458a 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template @@ -397,6 +397,25 @@ relativeError)); } } + static void assertSelectFromTwoVectorEquals($type$[] r, $type$[] order, $type$[] a, $type$[] b, int vector_len) { + int i = 0, j = 0; + boolean is_exceptional_idx = false; + int idx = 0, wrapped_index = 0, oidx = 0; + try { + for (; i < a.length; i += vector_len) { + for (j = 0; j < vector_len; j++) { + idx = i + j; + wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len); + is_exceptional_idx = wrapped_index >= vector_len; + oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index; + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx])); + } + } + } catch (AssertionError e) { + Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]); + } + } + static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, int vector_len) { int i = 0, j = 0; try { @@ -1221,6 +1240,18 @@ relativeError)); flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). collect(Collectors.toList()); + static final List> SELECT_FROM_INDEX_GENERATORS = List.of( + withToString("$type$[0..VECLEN*2)", (int s) -> { + return fill(s * BUFFER_REPS, + i -> ($type$)(RAND.nextInt())); + }) + ); + + static final List>> $TYPE$_GENERATOR_SELECT_FROM_TRIPLES = + $TYPE$_GENERATOR_PAIRS.stream(). + flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). + collect(Collectors.toList()); + @DataProvider public Object[][] $type$BinaryOpProvider() { return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray). @@ -1248,6 +1279,12 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] $type$SelectFromTwoVectorOpProvider() { + return $TYPE$_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray). + toArray(Object[][]::new); + } + @DataProvider public Object[][] $type$TernaryOpMaskProvider() { return BOOLEAN_MASK_GENERATORS.stream(). diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/SelectFromBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/SelectFromBenchmark.java new file mode 100644 index 00000000000..18614617e6c --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/SelectFromBenchmark.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.Random; +import java.util.Arrays; +import jdk.incubator.vector.*; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class SelectFromBenchmark { + @Param({"1024","2048"}) + int size; + + byte[] byteindex; + byte[] bytesrc1; + byte[] bytesrc2; + byte[] byteres; + + short[] shortindex; + short[] shortsrc1; + short[] shortsrc2; + short[] shortres; + + int[] intindex; + int[] intsrc1; + int[] intsrc2; + int[] intres; + + long[] longindex; + long[] longsrc1; + long[] longsrc2; + long[] longres; + + float[] floatindex; + float[] floatsrc1; + float[] floatsrc2; + float[] floatres; + + double[] doubleindex; + double[] doublesrc1; + double[] doublesrc2; + double[] doubleres; + + @Setup(Level.Trial) + public void BmSetup() { + Random r = new Random(1024); + byteindex = new byte[size]; + bytesrc1 = new byte[size]; + bytesrc2 = new byte[size]; + byteres = new byte[size]; + + shortindex = new short[size]; + shortsrc1 = new short[size]; + shortsrc2 = new short[size]; + shortres = new short[size]; + + intindex = new int[size]; + intsrc1 = new int[size]; + intsrc2 = new int[size]; + intres = new int[size]; + + longindex = new long[size]; + longsrc1 = new long[size]; + longsrc2 = new long[size]; + longres = new long[size]; + + floatindex = new float[size]; + floatsrc1 = new float[size]; + floatsrc2 = new float[size]; + floatres = new float[size]; + + doubleindex = new double[size]; + doublesrc1 = new double[size]; + doublesrc2 = new double[size]; + doubleres = new double[size]; + + Arrays.fill(bytesrc1, (byte)1); + Arrays.fill(bytesrc2, (byte)2); + + Arrays.fill(shortsrc1, (short)1); + Arrays.fill(shortsrc2, (short)2); + + Arrays.fill(intsrc1, 1); + Arrays.fill(intsrc2, 2); + + Arrays.fill(longsrc1, 1); + Arrays.fill(longsrc2, 2); + + Arrays.fill(floatsrc1, 1.0f); + Arrays.fill(floatsrc2, 2.0f); + + Arrays.fill(doublesrc1, 1.0); + Arrays.fill(doublesrc2, 2.0); + + for (int i = 0; i < size; i++) { + byteindex[i] = (byte)((ByteVector.SPECIES_PREFERRED.length() - 1) & i); + shortindex[i] = (short)((ShortVector.SPECIES_PREFERRED.length() - 1) & i); + intindex[i] = (int)((IntVector.SPECIES_PREFERRED.length() - 1) & i); + longindex[i] = (long)((LongVector.SPECIES_PREFERRED.length() - 1) & i); + floatindex[i] = (float)((FloatVector.SPECIES_PREFERRED.length() - 1) & i); + doubleindex[i] = (double)((DoubleVector.SPECIES_PREFERRED.length() - 1) & i); + } + } + + @Benchmark + public void selectFromByteVector() { + for (int j = 0; j < size; j += ByteVector.SPECIES_PREFERRED.length()) { + ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, byteindex, j) + .selectFrom(ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc1, j), + ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc2, j)) + .intoArray(byteres, j); + } + } + + @Benchmark + public void rearrangeFromByteVector() { + for (int j = 0; j < size; j += ByteVector.SPECIES_PREFERRED.length()) { + ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc1, j) + .rearrange(ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, byteindex, j).toShuffle(), + ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc2, j)) + .intoArray(byteres, j); + } + } + + @Benchmark + public void selectFromShortVector() { + for (int j = 0; j < size; j += ShortVector.SPECIES_PREFERRED.length()) { + ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortindex, j) + .selectFrom(ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc1, j), + ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc2, j)) + .intoArray(shortres, j); + } + } + + @Benchmark + public void rearrangeFromShortVector() { + for (int j = 0; j < size; j += ShortVector.SPECIES_PREFERRED.length()) { + ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc1, j) + .rearrange(ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortindex, j).toShuffle(), + ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc2, j)) + .intoArray(shortres, j); + } + } + + @Benchmark + public void selectFromIntVector() { + for (int j = 0; j < size; j += IntVector.SPECIES_PREFERRED.length()) { + IntVector.fromArray(IntVector.SPECIES_PREFERRED, intindex, j) + .selectFrom(IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc1, j), + IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc2, j)) + .intoArray(intres, j); + } + } + + @Benchmark + public void rearrangeFromIntVector() { + for (int j = 0; j < size; j += IntVector.SPECIES_PREFERRED.length()) { + IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc1, j) + .rearrange(IntVector.fromArray(IntVector.SPECIES_PREFERRED, intindex, j).toShuffle(), + IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc2, j)) + .intoArray(intres, j); + } + } + + @Benchmark + public void selectFromLongVector() { + for (int j = 0; j < size; j += LongVector.SPECIES_PREFERRED.length()) { + LongVector.fromArray(LongVector.SPECIES_PREFERRED, longindex, j) + .selectFrom(LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc1, j), + LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc2, j)) + .intoArray(longres, j); + } + } + + @Benchmark + public void rearrangeFromLongVector() { + for (int j = 0; j < size; j += LongVector.SPECIES_PREFERRED.length()) { + LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc1, j) + .rearrange(LongVector.fromArray(LongVector.SPECIES_PREFERRED, longindex, j).toShuffle(), + LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc2, j)) + .intoArray(longres, j); + } + } + + @Benchmark + public void selectFromFloatVector() { + for (int j = 0; j < size; j += FloatVector.SPECIES_PREFERRED.length()) { + FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatindex, j) + .selectFrom(FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc1, j), + FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc2, j)) + .intoArray(floatres, j); + } + } + + @Benchmark + public void rearrangeFromFloatVector() { + for (int j = 0; j < size; j += FloatVector.SPECIES_PREFERRED.length()) { + FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc1, j) + .rearrange(FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatindex, j).toShuffle(), + FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc2, j)) + .intoArray(floatres, j); + } + } + + @Benchmark + public void selectFromDoubleVector() { + for (int j = 0; j < size; j += DoubleVector.SPECIES_PREFERRED.length()) { + DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doubleindex, j) + .selectFrom(DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc1, j), + DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc2, j)) + .intoArray(doubleres, j); + } + } + + @Benchmark + public void rearrangeFromDoubleVector() { + for (int j = 0; j < size; j += DoubleVector.SPECIES_PREFERRED.length()) { + DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc1, j) + .rearrange(DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doubleindex, j).toShuffle(), + DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc2, j)) + .intoArray(doubleres, j); + } + } +}