8283726: x86_64 intrinsics for compareUnsigned method in Integer and Long
Reviewed-by: kvn, jbhateja
This commit is contained in:
parent
b96ba19807
commit
108cd69516
@ -13022,6 +13022,32 @@ instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero)
|
||||
ins_pipe(ialu_cr_reg_mem);
|
||||
%}
|
||||
|
||||
// Manifest a CmpU result in an integer register. Very painful.
|
||||
// This is the test to avoid.
|
||||
instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags)
|
||||
%{
|
||||
match(Set dst (CmpU3 src1 src2));
|
||||
effect(KILL flags);
|
||||
|
||||
ins_cost(275); // XXX
|
||||
format %{ "cmpl $src1, $src2\t# CmpL3\n\t"
|
||||
"movl $dst, -1\n\t"
|
||||
"jb,u done\n\t"
|
||||
"setne $dst\n\t"
|
||||
"movzbl $dst, $dst\n\t"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Label done;
|
||||
__ cmpl($src1$$Register, $src2$$Register);
|
||||
__ movl($dst$$Register, -1);
|
||||
__ jccb(Assembler::below, done);
|
||||
__ setne($dst$$Register);
|
||||
__ movzbl($dst$$Register, $dst$$Register);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// Manifest a CmpL result in an integer register. Very painful.
|
||||
// This is the test to avoid.
|
||||
instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
|
||||
@ -13048,6 +13074,32 @@ instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// Manifest a CmpUL result in an integer register. Very painful.
|
||||
// This is the test to avoid.
|
||||
instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
|
||||
%{
|
||||
match(Set dst (CmpUL3 src1 src2));
|
||||
effect(KILL flags);
|
||||
|
||||
ins_cost(275); // XXX
|
||||
format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
|
||||
"movl $dst, -1\n\t"
|
||||
"jb,u done\n\t"
|
||||
"setne $dst\n\t"
|
||||
"movzbl $dst, $dst\n\t"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Label done;
|
||||
__ cmpq($src1$$Register, $src2$$Register);
|
||||
__ movl($dst$$Register, -1);
|
||||
__ jccb(Assembler::below, done);
|
||||
__ setne($dst$$Register);
|
||||
__ movzbl($dst$$Register, $dst$$Register);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// Unsigned long compare Instructions; really, same as signed long except they
|
||||
// produce an rFlagsRegU instead of rFlagsReg.
|
||||
instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2)
|
||||
|
@ -126,6 +126,7 @@ class methodHandle;
|
||||
do_signature(float2_float_signature, "(FF)F") \
|
||||
do_signature(float3_float_signature, "(FFF)F") \
|
||||
do_signature(int2_int_signature, "(II)I") \
|
||||
do_signature(long2_int_signature, "(JJ)I") \
|
||||
do_signature(long2_long_signature, "(JJ)J") \
|
||||
\
|
||||
/* here are the math names, all together: */ \
|
||||
@ -150,9 +151,9 @@ class methodHandle;
|
||||
do_name(expand_name,"expand") \
|
||||
\
|
||||
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
|
||||
do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \
|
||||
do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \
|
||||
do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \
|
||||
do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \
|
||||
do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \
|
||||
do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \
|
||||
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
|
||||
do_intrinsic(_floor, java_lang_Math, floor_name, double_double_signature, F_S) \
|
||||
do_intrinsic(_ceil, java_lang_Math, ceil_name, double_double_signature, F_S) \
|
||||
@ -205,7 +206,7 @@ class methodHandle;
|
||||
do_intrinsic(_dsqrt_strict, java_lang_StrictMath, sqrt_name, double_double_signature, F_SN) \
|
||||
\
|
||||
do_intrinsic(_floatIsInfinite, java_lang_Float, isInfinite_name, float_bool_signature, F_S) \
|
||||
do_name( isInfinite_name, "isInfinite") \
|
||||
do_name( isInfinite_name, "isInfinite") \
|
||||
do_intrinsic(_doubleIsInfinite, java_lang_Double, isInfinite_name, double_bool_signature, F_S) \
|
||||
\
|
||||
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_SN) \
|
||||
@ -221,12 +222,17 @@ class methodHandle;
|
||||
do_intrinsic(_longBitsToDouble, java_lang_Double, longBitsToDouble_name, long_double_signature, F_SN)\
|
||||
do_name( longBitsToDouble_name, "longBitsToDouble") \
|
||||
\
|
||||
do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \
|
||||
do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \
|
||||
do_name( divideUnsigned_name, "divideUnsigned") \
|
||||
do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \
|
||||
do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \
|
||||
do_name( remainderUnsigned_name, "remainderUnsigned") \
|
||||
do_intrinsic(_compareUnsigned_i, java_lang_Integer, compareUnsigned_name, int2_int_signature, F_S) \
|
||||
do_intrinsic(_compareUnsigned_l, java_lang_Long, compareUnsigned_name, long2_int_signature, F_S) \
|
||||
do_name( compareUnsigned_name, "compareUnsigned") \
|
||||
\
|
||||
do_intrinsic(_divideUnsigned_i, java_lang_Integer, divideUnsigned_name, int2_int_signature, F_S) \
|
||||
do_intrinsic(_remainderUnsigned_i, java_lang_Integer, remainderUnsigned_name, int2_int_signature, F_S) \
|
||||
do_name( divideUnsigned_name, "divideUnsigned") \
|
||||
do_intrinsic(_divideUnsigned_l, java_lang_Long, divideUnsigned_name, long2_long_signature, F_S) \
|
||||
do_intrinsic(_remainderUnsigned_l, java_lang_Long, remainderUnsigned_name, long2_long_signature, F_S) \
|
||||
do_name( remainderUnsigned_name, "remainderUnsigned") \
|
||||
\
|
||||
do_intrinsic(_numberOfLeadingZeros_i, java_lang_Integer, numberOfLeadingZeros_name,int_int_signature, F_S) \
|
||||
do_intrinsic(_numberOfLeadingZeros_l, java_lang_Long, numberOfLeadingZeros_name,long_int_signature, F_S) \
|
||||
\
|
||||
|
@ -275,6 +275,12 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
|
||||
case vmIntrinsics::_reverseBytes_l:
|
||||
if (!Matcher::match_rule_supported(Op_ReverseBytesL)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_compareUnsigned_i:
|
||||
if (!Matcher::match_rule_supported(Op_CmpU3)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_compareUnsigned_l:
|
||||
if (!Matcher::match_rule_supported(Op_CmpUL3)) return false;
|
||||
break;
|
||||
case vmIntrinsics::_divideUnsigned_i:
|
||||
if (!Matcher::match_rule_supported(Op_UDivI)) return false;
|
||||
break;
|
||||
|
@ -97,7 +97,9 @@ macro(CmpL3)
|
||||
macro(CmpLTMask)
|
||||
macro(CmpP)
|
||||
macro(CmpU)
|
||||
macro(CmpU3)
|
||||
macro(CmpUL)
|
||||
macro(CmpUL3)
|
||||
macro(CompareAndSwapB)
|
||||
macro(CompareAndSwapS)
|
||||
macro(CompareAndSwapI)
|
||||
|
@ -535,6 +535,9 @@ bool LibraryCallKit::try_to_inline(int predicate) {
|
||||
case vmIntrinsics::_expand_i:
|
||||
case vmIntrinsics::_expand_l: return inline_bitshuffle_methods(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_compareUnsigned_i:
|
||||
case vmIntrinsics::_compareUnsigned_l: return inline_compare_unsigned(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_divideUnsigned_i:
|
||||
case vmIntrinsics::_divideUnsigned_l:
|
||||
case vmIntrinsics::_remainderUnsigned_i:
|
||||
@ -2247,6 +2250,22 @@ bool LibraryCallKit::inline_bitshuffle_methods(vmIntrinsics::ID id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------inline_number_methods-----------------------------
|
||||
// inline int Integer.compareUnsigned(int, int)
|
||||
// inline int Long.compareUnsigned(long, long)
|
||||
bool LibraryCallKit::inline_compare_unsigned(vmIntrinsics::ID id) {
|
||||
Node* arg1 = argument(0);
|
||||
Node* arg2 = (id == vmIntrinsics::_compareUnsigned_l) ? argument(2) : argument(1);
|
||||
Node* n = NULL;
|
||||
switch (id) {
|
||||
case vmIntrinsics::_compareUnsigned_i: n = new CmpU3Node(arg1, arg2); break;
|
||||
case vmIntrinsics::_compareUnsigned_l: n = new CmpUL3Node(arg1, arg2); break;
|
||||
default: fatal_unexpected_iid(id); break;
|
||||
}
|
||||
set_result(_gvn.transform(n));
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------inline_unsigned_divmod_methods-----------------------------
|
||||
// inline int Integer.divideUnsigned(int, int)
|
||||
// inline int Integer.remainderUnsigned(int, int)
|
||||
|
@ -277,6 +277,7 @@ class LibraryCallKit : public GraphKit {
|
||||
bool inline_fp_range_check(vmIntrinsics::ID id);
|
||||
bool inline_number_methods(vmIntrinsics::ID id);
|
||||
bool inline_bitshuffle_methods(vmIntrinsics::ID id);
|
||||
bool inline_compare_unsigned(vmIntrinsics::ID id);
|
||||
bool inline_divmod_methods(vmIntrinsics::ID id);
|
||||
bool inline_reference_get();
|
||||
bool inline_reference_refersTo0(bool is_phantom);
|
||||
|
@ -848,8 +848,12 @@ bool CmpUNode::is_index_range_check() const {
|
||||
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
|
||||
if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
|
||||
switch (in(1)->Opcode()) {
|
||||
case Op_CmpU3: // Collapse a CmpU3/CmpI into a CmpU
|
||||
return new CmpUNode(in(1)->in(1),in(1)->in(2));
|
||||
case Op_CmpL3: // Collapse a CmpL3/CmpI into a CmpL
|
||||
return new CmpLNode(in(1)->in(1),in(1)->in(2));
|
||||
case Op_CmpUL3: // Collapse a CmpUL3/CmpI into a CmpUL
|
||||
return new CmpULNode(in(1)->in(1),in(1)->in(2));
|
||||
case Op_CmpF3: // Collapse a CmpF3/CmpI into a CmpF
|
||||
return new CmpFNode(in(1)->in(1),in(1)->in(2));
|
||||
case Op_CmpD3: // Collapse a CmpD3/CmpI into a CmpD
|
||||
|
@ -173,6 +173,18 @@ public:
|
||||
bool is_index_range_check() const;
|
||||
};
|
||||
|
||||
//------------------------------CmpU3Node--------------------------------------
|
||||
// Compare 2 unsigned values, returning integer value (-1, 0 or 1).
|
||||
class CmpU3Node : public CmpUNode {
|
||||
public:
|
||||
CmpU3Node( Node *in1, Node *in2 ) : CmpUNode(in1,in2) {
|
||||
// Since it is not consumed by Bools, it is not really a Cmp.
|
||||
init_class_id(Class_Sub);
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//------------------------------CmpPNode---------------------------------------
|
||||
// Compare 2 pointer values, returning condition codes (-1, 0 or 1).
|
||||
class CmpPNode : public CmpNode {
|
||||
@ -220,7 +232,19 @@ public:
|
||||
// Since it is not consumed by Bools, it is not really a Cmp.
|
||||
init_class_id(Class_Sub);
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
virtual int Opcode() const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//------------------------------CmpUL3Node-------------------------------------
|
||||
// Compare 2 unsigned long values, returning integer value (-1, 0 or 1).
|
||||
class CmpUL3Node : public CmpULNode {
|
||||
public:
|
||||
CmpUL3Node( Node *in1, Node *in2 ) : CmpULNode(in1,in2) {
|
||||
// Since it is not consumed by Bools, it is not really a Cmp.
|
||||
init_class_id(Class_Sub);
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
|
@ -1708,11 +1708,13 @@
|
||||
declare_c2_type(CmpNode, SubNode) \
|
||||
declare_c2_type(CmpINode, CmpNode) \
|
||||
declare_c2_type(CmpUNode, CmpNode) \
|
||||
declare_c2_type(CmpU3Node, CmpUNode) \
|
||||
declare_c2_type(CmpPNode, CmpNode) \
|
||||
declare_c2_type(CmpNNode, CmpNode) \
|
||||
declare_c2_type(CmpLNode, CmpNode) \
|
||||
declare_c2_type(CmpULNode, CmpNode) \
|
||||
declare_c2_type(CmpL3Node, CmpLNode) \
|
||||
declare_c2_type(CmpUL3Node, CmpULNode) \
|
||||
declare_c2_type(CmpFNode, CmpNode) \
|
||||
declare_c2_type(CmpF3Node, CmpFNode) \
|
||||
declare_c2_type(CmpDNode, CmpNode) \
|
||||
|
@ -1500,6 +1500,7 @@ public final class Integer extends Number
|
||||
* unsigned values
|
||||
* @since 1.8
|
||||
*/
|
||||
@IntrinsicCandidate
|
||||
public static int compareUnsigned(int x, int y) {
|
||||
return compare(x + MIN_VALUE, y + MIN_VALUE);
|
||||
}
|
||||
|
@ -1641,6 +1641,7 @@ public final class Long extends Number
|
||||
* unsigned values
|
||||
* @since 1.8
|
||||
*/
|
||||
@IntrinsicCandidate
|
||||
public static int compareUnsigned(long x, long y) {
|
||||
return compare(x + MIN_VALUE, y + MIN_VALUE);
|
||||
}
|
||||
|
102
test/hotspot/jtreg/compiler/intrinsics/TestCompareUnsigned.java
Normal file
102
test/hotspot/jtreg/compiler/intrinsics/TestCompareUnsigned.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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 compiler.intrinsics;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key randomness
|
||||
* @bug 8283726
|
||||
* @requires os.arch=="amd64" | os.arch=="x86_64"
|
||||
* @summary Test the intrinsics implementation of Integer/Long::compareUnsigned
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.intrinsics.TestCompareUnsigned
|
||||
*/
|
||||
public class TestCompareUnsigned {
|
||||
static final int TRUE_VALUE = 10;
|
||||
static final int FALSE_VALUE = 4;
|
||||
|
||||
public static void main(String[] args) {
|
||||
var test = new TestFramework(TestCompareUnsigned.class);
|
||||
test.setDefaultWarmup(1);
|
||||
test.start();
|
||||
}
|
||||
|
||||
static int expectedResult(int x, int y) {
|
||||
return Integer.compare(x + Integer.MIN_VALUE, y + Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
static int expectedResult(long x, long y) {
|
||||
return Long.compare(x + Long.MIN_VALUE, y + Long.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.CMP_U3})
|
||||
@IR(counts = {IRNode.CMP_U, "1"})
|
||||
public int lessThanInt(int x, int y) {
|
||||
return Integer.compareUnsigned(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.CMP_UL3})
|
||||
@IR(counts = {IRNode.CMP_UL, "1"})
|
||||
public int lessThanLong(long x, long y) {
|
||||
return Long.compareUnsigned(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE;
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.CMP_U3, "1"})
|
||||
public int compareInt(int x, int y) {
|
||||
return Integer.compareUnsigned(x, y);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.CMP_UL3, "1"})
|
||||
public int compareLong(long x, long y) {
|
||||
return Long.compareUnsigned(x, y);
|
||||
}
|
||||
|
||||
@Run(test = {"lessThanInt", "lessThanLong", "compareInt", "compareLong"})
|
||||
public void runTests() {
|
||||
var random = Utils.getRandomInstance();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
int x = random.nextInt();
|
||||
int y = random.nextInt();
|
||||
Asserts.assertEquals(lessThanInt(x, x), FALSE_VALUE);
|
||||
Asserts.assertEquals(compareInt(x, x), 0);
|
||||
Asserts.assertEquals(lessThanInt(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);
|
||||
Asserts.assertEquals(compareInt(x, y), expectedResult(x, y));
|
||||
}
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
long x = random.nextLong();
|
||||
long y = random.nextLong();
|
||||
Asserts.assertEquals(lessThanLong(x, x), FALSE_VALUE);
|
||||
Asserts.assertEquals(compareLong(x, x), 0);
|
||||
Asserts.assertEquals(lessThanLong(x, y), expectedResult(x, y) < 0 ? TRUE_VALUE : FALSE_VALUE);
|
||||
Asserts.assertEquals(compareLong(x, y), expectedResult(x, y));
|
||||
}
|
||||
}
|
||||
}
|
@ -172,6 +172,10 @@ public class IRNode {
|
||||
public static final String SUB_L = START + "SubL" + MID + END;
|
||||
public static final String SUB_F = START + "SubF" + MID + END;
|
||||
public static final String SUB_D = START + "SubD" + MID + END;
|
||||
public static final String CMP_U = START + "CmpU" + MID + END;
|
||||
public static final String CMP_UL = START + "CmpUL" + MID + END;
|
||||
public static final String CMP_U3 = START + "CmpU3" + MID + END;
|
||||
public static final String CMP_UL3 = START + "CmpUL3" + MID + END;
|
||||
public static final String MUL = START + "Mul(I|L|F|D)" + MID + END;
|
||||
public static final String MUL_I = START + "MulI" + MID + END;
|
||||
public static final String MUL_L = START + "MulL" + MID + END;
|
||||
|
@ -52,6 +52,7 @@ public class Integers {
|
||||
@Param("500")
|
||||
private int size;
|
||||
|
||||
private int bound;
|
||||
private String[] strings;
|
||||
private int[] intsTiny;
|
||||
private int[] intsSmall;
|
||||
@ -60,6 +61,7 @@ public class Integers {
|
||||
@Setup
|
||||
public void setup() {
|
||||
Random r = new Random(0);
|
||||
bound = 50;
|
||||
strings = new String[size];
|
||||
intsTiny = new int[size];
|
||||
intsSmall = new int[size];
|
||||
@ -146,4 +148,20 @@ public class Integers {
|
||||
bh.consume(intsBig[i] << intsSmall[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void compareUnsignedIndirect(Blackhole bh) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int r = (Integer.compareUnsigned(intsSmall[i], bound - 16) < 0) ? 1 : 0;
|
||||
bh.consume(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void compareUnsignedDirect(Blackhole bh) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int r = Integer.compareUnsigned(intsSmall[i], bound - 16);
|
||||
bh.consume(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ public class Longs {
|
||||
@Param("500")
|
||||
private int size;
|
||||
|
||||
private long bound;
|
||||
private String[] strings;
|
||||
private long[] longArraySmall;
|
||||
private long[] longArrayBig;
|
||||
@ -56,6 +57,7 @@ public class Longs {
|
||||
@Setup
|
||||
public void setup() {
|
||||
var random = ThreadLocalRandom.current();
|
||||
bound = 20000L;
|
||||
strings = new String[size];
|
||||
longArraySmall = new long[size];
|
||||
longArrayBig = new long[size];
|
||||
@ -141,4 +143,20 @@ public class Longs {
|
||||
bh.consume(longArrayBig[i] << longArraySmall[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void compareUnsignedIndirect(Blackhole bh) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int r = (Long.compareUnsigned(longArraySmall[i], bound - 16) < 0) ? 1 : 0;
|
||||
bh.consume(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void compareUnsignedDirect(Blackhole bh) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int r = Long.compareUnsigned(longArraySmall[i], bound - 16);
|
||||
bh.consume(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user