diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index 5ecc038954dd4..f5f7a4231f261 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -1216,6 +1216,9 @@ bool Node::has_special_unique_user() const { } else if ((is_IfFalse() || is_IfTrue()) && n->is_If()) { // See IfNode::fold_compares return true; + } else if (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) { + // Condition for XorVMask(VectorMaskCmp(x,y,cond), MaskAll(true)) ==> VectorMaskCmp(x,y,ncond) + return true; } else { return false; } diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index 57a501ecbc37f..5acf31b45c4bb 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -328,7 +328,9 @@ struct BoolTest { // a simple char array where each element is the ASCII version of a 'mask' // enum from above. mask commute( ) const { return mask("032147658"[_test]-'0'); } - mask negate( ) const { return mask(_test^4); } + mask negate( ) const { return negate_mask(_test); } + // Return the negative mask for the given mask, for both signed and unsigned comparison. + static mask negate_mask(mask btm) { return mask(btm ^ 4); } bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } bool is_less( ) const { return _test == BoolTest::lt || _test == BoolTest::le; } bool is_greater( ) const { return _test == BoolTest::gt || _test == BoolTest::ge; } diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 2153a12c40222..ae9ef552df4b5 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -2268,6 +2268,99 @@ Node* OrVNode::Identity(PhaseGVN* phase) { return redundant_logical_identity(this); } +// Returns whether (XorV (VectorMaskCmp) -1) can be optimized by negating the +// comparison operation. +bool VectorMaskCmpNode::predicate_can_be_negated() { + switch (_predicate) { + case BoolTest::eq: + case BoolTest::ne: + // eq and ne also apply to floating-point special values like NaN and infinities. + return true; + case BoolTest::le: + case BoolTest::ge: + case BoolTest::lt: + case BoolTest::gt: + case BoolTest::ule: + case BoolTest::uge: + case BoolTest::ult: + case BoolTest::ugt: { + BasicType bt = vect_type()->element_basic_type(); + // For float and double, we don't know if either comparison operand is a + // NaN, NaN {le|ge|lt|gt} anything is false, resulting in inconsistent + // results before and after negation. + return is_integral_type(bt); + } + default: + return false; + } +} + +// This function transforms the following patterns: +// +// For integer types: +// (XorV (VectorMaskCmp src1 src2 cond) (Replicate -1)) +// => (VectorMaskCmp src1 src2 ncond) +// (XorVMask (VectorMaskCmp src1 src2 cond) (MaskAll m1)) +// => (VectorMaskCmp src1 src2 ncond) +// (XorV (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (Replicate -1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// (XorVMask (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (MaskAll m1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// cond can be eq, ne, le, ge, lt, gt, ule, uge, ult and ugt. +// ncond is the negative comparison of cond. +// +// For float and double types: +// (XorV (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (Replicate -1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// (XorVMask (VectorMaskCast (VectorMaskCmp src1 src2 cond)) (MaskAll m1)) +// => (VectorMaskCast (VectorMaskCmp src1 src2 ncond)) +// cond can be eq or ne. +Node* XorVNode::Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape) { + Node* in1 = in(1); + Node* in2 = in(2); + // Transformations for predicated vectors are not supported for now. + if (is_predicated_vector() || + in1->is_predicated_vector() || + in2->is_predicated_vector()) { + return nullptr; + } + + // XorV/XorVMask is commutative, swap VectorMaskCmp/VectorMaskCast to in1. + if (VectorNode::is_all_ones_vector(in1)) { + swap(in1, in2); + } + + bool with_vector_mask_cast = false; + // Required conditions: + // 1. VectorMaskCast and VectorMaskCmp should only have a single use, + // otherwise the optimization may be unprofitable. + // 2. The predicate of VectorMaskCmp should be negatable. + // 3. The second input should be an all true vector mask. + if (in1->Opcode() == Op_VectorMaskCast) { + if (in1->outcnt() != 1) { + return nullptr; + } + with_vector_mask_cast = true; + in1 = in1->in(1); + } + if (in1->Opcode() != Op_VectorMaskCmp || + in1->outcnt() != 1 || + !in1->as_VectorMaskCmp()->predicate_can_be_negated() || + !VectorNode::is_all_ones_vector(in2)) { + return nullptr; + } + + BoolTest::mask neg_cond = BoolTest::negate_mask((in1->as_VectorMaskCmp())->get_predicate()); + ConINode* predicate_node = phase->intcon(neg_cond); + const TypeVect* vt = in1->as_Vector()->vect_type(); + Node* res = new VectorMaskCmpNode(neg_cond, in1->in(1), in1->in(2), predicate_node, vt); + if (with_vector_mask_cast) { + // We optimized out a VectorMaskCast, regenerate one to ensure type correctness. + res = new VectorMaskCastNode(phase->transform(res), vect_type()); + } + return res; +} + Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) { // (XorV src src) => (Replicate zero) // (XorVMask src src) => (MaskAll zero) @@ -2281,6 +2374,11 @@ Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) { Node* zero = phase->transform(phase->zerocon(bt)); return VectorNode::scalar2vector(zero, length(), bt, bottom_type()->isa_vectmask() != nullptr); } + + Node* res = Ideal_XorV_VectorMaskCmp(phase, can_reshape); + if (res != nullptr) { + return res; + } return VectorNode::Ideal(phase, can_reshape); } diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 463680d0a52dd..53778b61d0e2f 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1013,6 +1013,7 @@ class XorVNode : public VectorNode { XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {} virtual int Opcode() const; virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); + Node* Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape); }; //------------------------------XorReductionVNode-------------------------------------- @@ -1676,6 +1677,7 @@ class VectorMaskCmpNode : public VectorNode { virtual bool cmp( const Node &n ) const { return VectorNode::cmp(n) && _predicate == ((VectorMaskCmpNode&)n)._predicate; } + bool predicate_can_be_negated(); BoolTest::mask get_predicate() { return _predicate; } #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 52fc9a05f98c3..bb69e5bfe80a5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -2295,6 +2295,11 @@ public class IRNode { vectorNode(VECTOR_MASK_CMP_D, "VectorMaskCmp", TYPE_DOUBLE); } + public static final String VECTOR_MASK_CMP = PREFIX + "VECTOR_MASK_CMP" + POSTFIX; + static { + beforeMatchingNameRegex(VECTOR_MASK_CMP, "VectorMaskCmp"); + } + public static final String VECTOR_CAST_B2S = VECTOR_PREFIX + "VECTOR_CAST_B2S" + POSTFIX; static { vectorNode(VECTOR_CAST_B2S, "VectorCastB2X", TYPE_SHORT); @@ -2705,6 +2710,11 @@ public class IRNode { vectorNode(XOR_VL, "XorV", TYPE_LONG); } + public static final String XOR_V = PREFIX + "XOR_V" + POSTFIX; + static { + beforeMatchingNameRegex(XOR_V, "XorV"); + } + public static final String XOR_V_MASK = PREFIX + "XOR_V_MASK" + POSTFIX; static { beforeMatchingNameRegex(XOR_V_MASK, "XorVMask"); diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java new file mode 100644 index 0000000000000..851113ea4dee5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskCompareNotTest.java @@ -0,0 +1,1299 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & 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 compiler.vectorapi; + +import compiler.lib.generators.*; +import compiler.lib.ir_framework.*; +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +/* + * @test + * @bug 8354242 + * @key randomness + * @library /test/lib / + * @summary test combining vector not operation with compare + * @modules jdk.incubator.vector + * + * @run driver compiler.vectorapi.VectorMaskCompareNotTest + */ + +public class VectorMaskCompareNotTest { + private static int LENGTH = 128; + + private static final VectorSpecies B_SPECIES = VectorSpecies.ofLargestShape(byte.class); + private static final VectorSpecies S_SPECIES = VectorSpecies.ofLargestShape(short.class); + private static final VectorSpecies I_SPECIES = VectorSpecies.ofLargestShape(int.class); + private static final VectorSpecies L_SPECIES = VectorSpecies.ofLargestShape(long.class); + private static final VectorSpecies F_SPECIES = VectorSpecies.ofLargestShape(float.class); + private static final VectorSpecies D_SPECIES = VectorSpecies.ofLargestShape(double.class); + + // Vector species for vector mask cast operation between int and long types, + // they must have the same number of elements. + // For other types, use a vector species of the specified width. + private static final VectorSpecies L_SPECIES_FOR_CAST = VectorSpecies.ofLargestShape(long.class); + private static final VectorSpecies I_SPECIES_FOR_CAST = VectorSpecies.of(int.class, VectorShape.forBitSize(L_SPECIES_FOR_CAST.vectorBitSize() / 2)); + + private static final Generators RD = Generators.G; + + private static byte[] ba; + private static byte[] bb; + private static short[] sa; + private static short[] sb; + private static int[] ia; + private static int[] ib; + private static int[] ic; + private static long[] la; + private static long[] lb; + private static float[] fa; + private static float[] fb; + private static float[] fnan; + private static float[] fpinf; + private static float[] fninf; + private static double[] da; + private static double[] db; + private static double[] dnan; + private static double[] dpinf; + private static double[] dninf; + private static boolean[] mr; + + static { + ba = new byte[LENGTH]; + bb = new byte[LENGTH]; + sa = new short[LENGTH]; + sb = new short[LENGTH]; + ia = new int[LENGTH]; + ib = new int[LENGTH]; + ic = new int[LENGTH]; + la = new long[LENGTH]; + lb = new long[LENGTH]; + fa = new float[LENGTH]; + fb = new float[LENGTH]; + fnan = new float[LENGTH]; + fpinf = new float[LENGTH]; + fninf = new float[LENGTH]; + da = new double[LENGTH]; + db = new double[LENGTH]; + dnan = new double[LENGTH]; + dpinf = new double[LENGTH]; + dninf = new double[LENGTH]; + mr = new boolean[LENGTH]; + + Generator iGen = RD.ints(); + Generator lGen = RD.longs(); + // Use uniform generators for floating point numbers not to generate NaN values. + Generator fGen = RD.uniformFloats(Float.MIN_VALUE, Float.MAX_VALUE); + Generator dGen = RD.uniformDoubles(Double.MIN_VALUE, Double.MAX_VALUE); + for (int i = 0; i < LENGTH; i++) { + ba[i] = iGen.next().byteValue(); + bb[i] = iGen.next().byteValue(); + sa[i] = iGen.next().shortValue(); + sb[i] = iGen.next().shortValue(); + ia[i] = iGen.next(); + ib[i] = iGen.next(); + la[i] = lGen.next(); + lb[i] = lGen.next(); + fa[i] = fGen.next(); + fb[i] = fGen.next(); + fnan[i] = Float.NaN; + fpinf[i] = Float.POSITIVE_INFINITY; + fninf[i] = Float.NEGATIVE_INFINITY; + da[i] = dGen.next(); + db[i] = dGen.next(); + dnan[i] = Double.NaN; + dpinf[i] = Double.POSITIVE_INFINITY; + dninf[i] = Double.NEGATIVE_INFINITY; + } + } + + public static int compareUnsigned(Number a, Number b) { + if (a instanceof Byte) { + return Integer.compareUnsigned(Byte.toUnsignedInt(a.byteValue()), Byte.toUnsignedInt(b.byteValue())); + } else if (a instanceof Short) { + return Integer.compareUnsigned(Short.toUnsignedInt(a.shortValue()), Short.toUnsignedInt(b.shortValue())); + } else if (a instanceof Integer) { + return Integer.compareUnsigned(a.intValue(), b.intValue()); + } else if (a instanceof Long) { + return Long.compareUnsigned(a.longValue(), b.longValue()); + } else { + throw new IllegalArgumentException("Unsupported type for unsigned comparison: " + a.getClass() + ", " + b.getClass()); + } + } + + public static > void compareResults(T a, T b, boolean r, VectorOperators.Comparison op) { + if (op == VectorOperators.EQ) { + // For floating point numbers, a is not NaN, b may be NaN. If b is NaN, + // a.compareTo(b) will return 1, 1 != 0 is true, r is expected to be true. + Asserts.assertEquals(a.compareTo(b) != 0, r); + } else if (op == VectorOperators.NE) { + // For floating point numbers, a is not NaN, b may be NaN. If b is NaN, + // a.compareTo(b) will return 1, 1 == 0 is false, r is expected to be false. + Asserts.assertEquals(a.compareTo(b) == 0, r); + } else if (op == VectorOperators.LE) { + Asserts.assertEquals(a.compareTo(b) > 0, r); + } else if (op == VectorOperators.GE) { + Asserts.assertEquals(a.compareTo(b) < 0, r); + } else if (op == VectorOperators.LT) { + Asserts.assertEquals(a.compareTo(b) >= 0, r); + } else if (op == VectorOperators.GT) { + Asserts.assertEquals(a.compareTo(b) <= 0, r); + } else if (op == VectorOperators.ULE) { + Asserts.assertEquals(compareUnsigned(a, b) > 0, r); + } else if (op == VectorOperators.UGE) { + Asserts.assertEquals(compareUnsigned(a, b) < 0, r); + } else if (op == VectorOperators.ULT) { + Asserts.assertEquals(compareUnsigned(a, b) >= 0, r); + } else if (op == VectorOperators.UGT) { + Asserts.assertEquals(compareUnsigned(a, b) <= 0, r); + } else { + throw new IllegalArgumentException("Unknown comparison operator: " + op); + } + } + + @DontInline + public static void verifyResultsByte(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(ba[i], bb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsShort(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(sa[i], sb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsInt(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(ia[i], ib[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsLong(VectorSpecies vs, VectorOperators.Comparison op) { + for (int i = 0; i < vs.length(); i++) { + compareResults(la[i], lb[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsFloat(VectorSpecies vs, VectorOperators.Comparison op, float[] a, float[] b) { + for (int i = 0; i < vs.length(); i++) { + compareResults(a[i], b[i], mr[i], op); + } + } + + @DontInline + public static void verifyResultsDouble(VectorSpecies vs, VectorOperators.Comparison op, double[] a, double[] b) { + for (int i = 0; i < vs.length(); i++) { + compareResults(a[i], b[i], mr[i], op); + } + } + + interface VectorMaskOperator { + public VectorMask apply(VectorMask m); + } + + @ForceInline + public static void testCompareMaskNotByte(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + ByteVector av = ByteVector.fromArray(vs, ba, 0); + ByteVector bv = ByteVector.fromArray(vs, bb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotShort(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + ShortVector av = ShortVector.fromArray(vs, sa, 0); + ShortVector bv = ShortVector.fromArray(vs, sb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotInt(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + IntVector av = IntVector.fromArray(vs, ia, 0); + IntVector bv = IntVector.fromArray(vs, ib, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotLong(VectorSpecies vs, VectorOperators.Comparison op, VectorMaskOperator func) { + LongVector av = LongVector.fromArray(vs, la, 0); + LongVector bv = LongVector.fromArray(vs, lb, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotFloat(VectorSpecies vs, VectorOperators.Comparison op, float[] a, float[] b, VectorMaskOperator func) { + FloatVector av = FloatVector.fromArray(vs, a, 0); + FloatVector bv = FloatVector.fromArray(vs, b, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + @ForceInline + public static void testCompareMaskNotDouble(VectorSpecies vs, VectorOperators.Comparison op, double[] a, double[] b, VectorMaskOperator func) { + DoubleVector av = DoubleVector.fromArray(vs, a, 0); + DoubleVector bv = DoubleVector.fromArray(vs, b, 0); + VectorMask m = av.compare(op, bv); + func.apply(m).intoArray(mr, 0); + } + + // Byte tests + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.EQ, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.NE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.NE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.LT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.LT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.LT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.LT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.GT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.GT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.GT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.GT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.LE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.LE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.LE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.LE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.GE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.GE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.GE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.GE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.ULT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGT); + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGT, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGT); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.UGT, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.ULE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.ULE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.ULE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotByte() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGE); + testCompareMaskNotByte(B_SPECIES, VectorOperators.UGE, (m) -> { return B_SPECIES.maskAll(true).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.UGE); + + testCompareMaskNotByte(ByteVector.SPECIES_64, VectorOperators.UGE, (m) -> { return m.cast(ShortVector.SPECIES_128).not(); }); + verifyResultsByte(ByteVector.SPECIES_64, VectorOperators.UGE); + } + + // Short tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.EQ, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.EQ); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.EQ, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.NE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.NE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.NE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.NE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.LT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.LT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.LT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.LT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.LT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.LT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.GT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.GT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.GT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.GT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.GT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.GT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareLEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.LE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.LE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.LE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.LE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.LE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.LE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareGEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.GE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.GE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.GE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.GE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.GE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.GE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.ULT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.ULT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.ULT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGT); + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGT, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGT); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.UGT, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.UGT); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.UGT, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareULEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.ULE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.ULE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.ULE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.ULE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.ULE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotShort() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGE); + testCompareMaskNotShort(S_SPECIES, VectorOperators.UGE, (m) -> { return S_SPECIES.maskAll(true).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.UGE); + + testCompareMaskNotShort(ShortVector.SPECIES_64, VectorOperators.UGE, (m) -> { return IntVector.SPECIES_128.maskAll(true).xor(m.cast(IntVector.SPECIES_128)); }); + verifyResultsShort(ShortVector.SPECIES_64, VectorOperators.UGE); + testCompareMaskNotShort(ShortVector.SPECIES_128, VectorOperators.UGE, (m) -> { return m.cast(ByteVector.SPECIES_64).not(); }); + verifyResultsShort(ShortVector.SPECIES_128, VectorOperators.UGE); + } + + // Int tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.EQ, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.EQ); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.EQ, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.NE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.NE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.NE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.NE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.LT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.LT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.LT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.LT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.LT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.LT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.GT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.GT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.GT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.GT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.GT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.GT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.LE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.LE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.LE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.LE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.LE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.LE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.GE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.GE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.GE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.GE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.GE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.GE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.ULT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.ULT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.ULT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGT); + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGT, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGT); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.UGT, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.UGT); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.UGT, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.ULE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.ULE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.ULE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.ULE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.ULE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 2", + IRNode.VECTOR_MASK_CMP, "= 4" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotInt() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGE); + testCompareMaskNotInt(I_SPECIES, VectorOperators.UGE, (m) -> { return I_SPECIES.maskAll(true).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.UGE); + + testCompareMaskNotInt(I_SPECIES_FOR_CAST, VectorOperators.UGE, (m) -> { return L_SPECIES_FOR_CAST.maskAll(true).xor(m.cast(L_SPECIES_FOR_CAST)); }); + verifyResultsInt(I_SPECIES_FOR_CAST, VectorOperators.UGE); + testCompareMaskNotInt(IntVector.SPECIES_128, VectorOperators.UGE, (m) -> { return m.cast(ShortVector.SPECIES_64).not(); }); + verifyResultsInt(IntVector.SPECIES_128, VectorOperators.UGE); + } + + // Long tests + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.EQ, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.EQ); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.NE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.NE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.NE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.LT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.LT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.LT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.LT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.LT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.LT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.GT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.GT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.GT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.GT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.GT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.GT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareLEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.LE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.LE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.LE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.LE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.LE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.LE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareGEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.GE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.GE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.GE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.GE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.GE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.GE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.ULT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.ULT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGTMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGT, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGT); + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGT, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGT); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.UGT, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.UGT); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareULEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.ULE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.ULE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.ULE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.ULE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CAST, "= 1", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareUGEMaskNotLong() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGE, (m) -> { return m.not(); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGE); + testCompareMaskNotLong(L_SPECIES, VectorOperators.UGE, (m) -> { return L_SPECIES.maskAll(true).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.UGE); + + testCompareMaskNotLong(L_SPECIES_FOR_CAST, VectorOperators.UGE, (m) -> { return m.cast(I_SPECIES_FOR_CAST).not(); }); + verifyResultsLong(L_SPECIES_FOR_CAST, VectorOperators.UGE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloat() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloat() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fb, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatNaN() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fnan, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fnan); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fnan, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatNaN() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fnan, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fnan); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fnan, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatPositiveInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatPositiveInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fpinf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fpinf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fpinf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareEQMaskNotFloatNegativeInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fninf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fninf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fninf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx", "true", "rvv", "true" }) + public static void testCompareNEMaskNotFloatNegativeInfinity() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fninf, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fninf); + testCompareMaskNotFloat(F_SPECIES, VectorOperators.NE, fa, fninf, (m) -> { return F_SPECIES.maskAll(true).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDouble() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDouble() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, db, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoubleNaN() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dnan, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dnan); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dnan, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoubleNaN() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dnan, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dnan); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dnan, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dnan); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoublePositiveInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dpinf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dpinf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dpinf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoublePositiveInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dpinf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dpinf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dpinf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dpinf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareEQMaskNotDoubleNegativeInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dninf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dninf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, dninf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, dninf); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 0", + IRNode.XOR_V, "= 0", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "asimd", "true", "avx2", "true", "rvv", "true" }) + public static void testCompareNEMaskNotDoubleNegativeInfinity() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dninf, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dninf); + testCompareMaskNotDouble(D_SPECIES, VectorOperators.NE, da, dninf, (m) -> { return D_SPECIES.maskAll(true).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, dninf); + } + + // negative tests + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotByteNegative() { + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsByte(B_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotByte(B_SPECIES, VectorOperators.EQ, (m) -> { return B_SPECIES.maskAll(false).xor(m); }); + verifyResultsByte(B_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotShortNegative() { + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsShort(S_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotShort(S_SPECIES, VectorOperators.EQ, (m) -> { return S_SPECIES.maskAll(false).xor(m); }); + verifyResultsShort(S_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotIntNegative() { + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsInt(I_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotInt(I_SPECIES, VectorOperators.EQ, (m) -> { return I_SPECIES.maskAll(false).xor(m); }); + verifyResultsInt(I_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 2", + IRNode.VECTOR_MASK_CMP, "= 2" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotLongNegative() { + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsLong(L_SPECIES, VectorOperators.EQ); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotLong(L_SPECIES, VectorOperators.EQ, (m) -> { return L_SPECIES.maskAll(false).xor(m); }); + verifyResultsLong(L_SPECIES, VectorOperators.NE); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotFloatNegative() { + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsFloat(F_SPECIES, VectorOperators.EQ, fa, fb); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotFloat(F_SPECIES, VectorOperators.EQ, fa, fb, (m) -> { return F_SPECIES.maskAll(false).xor(m); }); + verifyResultsFloat(F_SPECIES, VectorOperators.NE, fa, fb); + + // Float vectors use the LT comparison. + testCompareMaskNotFloat(F_SPECIES, VectorOperators.LT, fa, fb, (m) -> { return m.not(); }); + verifyResultsFloat(F_SPECIES, VectorOperators.LT, fa, fb); + } + + @Test + @IR(counts = { IRNode.XOR_V_MASK, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureOr = { "sve", "true", "avx512", "true", "rvv", "true" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" }) + @IR(counts = { IRNode.XOR_V, "= 3", + IRNode.VECTOR_MASK_CMP, "= 3" }, + applyIfCPUFeatureAnd = { "avx2", "true" }) + public static void testCompareMaskNotDoubleNegative() { + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { + // The vector mask is used multiple times. + ic[0] = m.trueCount(); + return m.not(); + }); + verifyResultsDouble(D_SPECIES, VectorOperators.EQ, da, db); + + // One of the operands of XOR is not all ones vector. + testCompareMaskNotDouble(D_SPECIES, VectorOperators.EQ, da, db, (m) -> { return D_SPECIES.maskAll(false).xor(m); }); + verifyResultsDouble(D_SPECIES, VectorOperators.NE, da, db); + + // Double vectors use the LT comparison. + testCompareMaskNotDouble(D_SPECIES, VectorOperators.LT, da, db, (m) -> { return m.not(); }); + verifyResultsDouble(D_SPECIES, VectorOperators.LT, da, db); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(5000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java new file mode 100644 index 0000000000000..d83bc126a1d06 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/MaskCompareNotBenchmark.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & 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 org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import jdk.incubator.vector.*; +import java.lang.invoke.*; +import java.util.concurrent.TimeUnit; +import java.util.Random; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 2, jvmArgs = { "--add-modules=jdk.incubator.vector" }) +public abstract class MaskCompareNotBenchmark { + @Param({"4096"}) + protected int ARRAYLEN; + + // Abstract method to get comparison operator from subclasses + protected abstract String getComparisonOperatorName(); + + // To get compile-time constants for comparison operation + static final MutableCallSite MUTABLE_COMPARISON_CONSTANT = new MutableCallSite(MethodType.methodType(VectorOperators.Comparison.class)); + static final MethodHandle MUTABLE_COMPARISON_CONSTANT_HANDLE = MUTABLE_COMPARISON_CONSTANT.dynamicInvoker(); + + private static Random r = new Random(); + + protected static final VectorSpecies B_SPECIES = ByteVector.SPECIES_MAX; + protected static final VectorSpecies S_SPECIES = ShortVector.SPECIES_MAX; + protected static final VectorSpecies I_SPECIES = IntVector.SPECIES_MAX; + protected static final VectorSpecies L_SPECIES = LongVector.SPECIES_MAX; + protected static final VectorSpecies F_SPECIES = FloatVector.SPECIES_MAX; + protected static final VectorSpecies D_SPECIES = DoubleVector.SPECIES_MAX; + + protected boolean[] mr; + protected byte[] ba; + protected byte[] bb; + protected short[] sa; + protected short[] sb; + protected int[] ia; + protected int[] ib; + protected long[] la; + protected long[] lb; + protected float[] fa; + protected float[] fb; + protected double[] da; + protected double[] db; + + @Setup + public void init() throws Throwable { + mr = new boolean[ARRAYLEN]; + ba = new byte[ARRAYLEN]; + bb = new byte[ARRAYLEN]; + sa = new short[ARRAYLEN]; + sb = new short[ARRAYLEN]; + ia = new int[ARRAYLEN]; + ib = new int[ARRAYLEN]; + la = new long[ARRAYLEN]; + lb = new long[ARRAYLEN]; + fa = new float[ARRAYLEN]; + fb = new float[ARRAYLEN]; + da = new double[ARRAYLEN]; + db = new double[ARRAYLEN]; + + for (int i = 0; i < ARRAYLEN; i++) { + mr[i] = r.nextBoolean(); + ba[i] = (byte) r.nextInt(); + bb[i] = (byte) r.nextInt(); + sa[i] = (short) r.nextInt(); + sb[i] = (short) r.nextInt(); + ia[i] = r.nextInt(); + ib[i] = r.nextInt(); + la[i] = r.nextLong(); + lb[i] = r.nextLong(); + fa[i] = r.nextFloat(); + fb[i] = r.nextFloat(); + da[i] = r.nextDouble(); + db[i] = r.nextDouble(); + } + + VectorOperators.Comparison comparisonOp = getComparisonOperator(getComparisonOperatorName()); + MethodHandle constant = MethodHandles.constant(VectorOperators.Comparison.class, comparisonOp); + MUTABLE_COMPARISON_CONSTANT.setTarget(constant); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private static VectorOperators.Comparison getComparisonOperator(String op) { + switch (op) { + case "EQ": return VectorOperators.EQ; + case "NE": return VectorOperators.NE; + case "LT": return VectorOperators.LT; + case "LE": return VectorOperators.LE; + case "GT": return VectorOperators.GT; + case "GE": return VectorOperators.GE; + case "ULT": return VectorOperators.ULT; + case "ULE": return VectorOperators.ULE; + case "UGT": return VectorOperators.UGT; + case "UGE": return VectorOperators.UGE; + default: throw new IllegalArgumentException("Unknown comparison operator: " + op); + } + } + + @CompilerControl(CompilerControl.Mode.INLINE) + protected VectorOperators.Comparison comparison_con() throws Throwable { + return (VectorOperators.Comparison) MUTABLE_COMPARISON_CONSTANT_HANDLE.invokeExact(); + } + + // Subclasses with different comparison operators + public static class IntegerComparisons extends MaskCompareNotBenchmark { + @Param({"EQ", "NE", "LT", "LE", "GT", "GE", "ULT", "ULE", "UGT", "UGE"}) + public String COMPARISON_OP; + + @Override + protected String getComparisonOperatorName() { + return COMPARISON_OP; + } + + @Benchmark + public void testCompareMaskNotByte() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + ByteVector bv = ByteVector.fromArray(B_SPECIES, bb, 0); + for (int j = 0; j < ARRAYLEN; j += B_SPECIES.length()) { + ByteVector av = ByteVector.fromArray(B_SPECIES, ba, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotShort() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + ShortVector bv = ShortVector.fromArray(S_SPECIES, sb, 0); + for (int j = 0; j < ARRAYLEN; j += S_SPECIES.length()) { + ShortVector av = ShortVector.fromArray(S_SPECIES, sa, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotInt() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + IntVector bv = IntVector.fromArray(I_SPECIES, ib, 0); + for (int j = 0; j < ARRAYLEN; j += I_SPECIES.length()) { + IntVector av = IntVector.fromArray(I_SPECIES, ia, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotLong() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + LongVector bv = LongVector.fromArray(L_SPECIES, lb, 0); + for (int j = 0; j < ARRAYLEN; j += L_SPECIES.length()) { + LongVector av = LongVector.fromArray(L_SPECIES, la, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + } + + public static class FloatingPointComparisons extends MaskCompareNotBenchmark { + // "ULT", "ULE", "UGT", "UGE" are not supported for floating point types + @Param({"EQ", "NE", "LT", "LE", "GT", "GE"}) + public String COMPARISON_OP; + + @Override + protected String getComparisonOperatorName() { + return COMPARISON_OP; + } + + @Benchmark + public void testCompareMaskNotFloat() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + FloatVector bv = FloatVector.fromArray(F_SPECIES, fb, 0); + for (int j = 0; j < ARRAYLEN; j += F_SPECIES.length()) { + FloatVector av = FloatVector.fromArray(F_SPECIES, fa, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + + @Benchmark + public void testCompareMaskNotDouble() throws Throwable { + VectorOperators.Comparison op = comparison_con(); + DoubleVector bv = DoubleVector.fromArray(D_SPECIES, db, 0); + for (int j = 0; j < ARRAYLEN; j += D_SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(D_SPECIES, da, j); + VectorMask m = av.compare(op, bv).not(); + m.intoArray(mr, j); + } + } + } +}