8357551: RISC-V: support CMoveF/D vectorization

Reviewed-by: fyang, luhenry
This commit is contained in:
Hamlin Li 2025-12-08 13:38:22 +00:00
parent b83bf0717e
commit 6700baa505
14 changed files with 3604 additions and 143 deletions

View File

@ -2067,6 +2067,83 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe
}
}
void C2_MacroAssembler::enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
FloatRegister dst, FloatRegister src, bool is_single) {
bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask;
int op_select = cmpFlag & (~unsigned_branch_mask);
switch (op_select) {
case BoolTest::eq:
cmov_fp_eq(op1, op2, dst, src, is_single);
break;
case BoolTest::ne:
cmov_fp_ne(op1, op2, dst, src, is_single);
break;
case BoolTest::le:
if (is_unsigned) {
cmov_fp_leu(op1, op2, dst, src, is_single);
} else {
cmov_fp_le(op1, op2, dst, src, is_single);
}
break;
case BoolTest::ge:
if (is_unsigned) {
cmov_fp_geu(op1, op2, dst, src, is_single);
} else {
cmov_fp_ge(op1, op2, dst, src, is_single);
}
break;
case BoolTest::lt:
if (is_unsigned) {
cmov_fp_ltu(op1, op2, dst, src, is_single);
} else {
cmov_fp_lt(op1, op2, dst, src, is_single);
}
break;
case BoolTest::gt:
if (is_unsigned) {
cmov_fp_gtu(op1, op2, dst, src, is_single);
} else {
cmov_fp_gt(op1, op2, dst, src, is_single);
}
break;
default:
assert(false, "unsupported compare condition");
ShouldNotReachHere();
}
}
void C2_MacroAssembler::enc_cmove_fp_cmp_fp(int cmpFlag,
FloatRegister op1, FloatRegister op2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
int op_select = cmpFlag & (~unsigned_branch_mask);
switch (op_select) {
case BoolTest::eq:
cmov_fp_cmp_fp_eq(op1, op2, dst, src, cmp_single, cmov_single);
break;
case BoolTest::ne:
cmov_fp_cmp_fp_ne(op1, op2, dst, src, cmp_single, cmov_single);
break;
case BoolTest::le:
cmov_fp_cmp_fp_le(op1, op2, dst, src, cmp_single, cmov_single);
break;
case BoolTest::ge:
cmov_fp_cmp_fp_ge(op1, op2, dst, src, cmp_single, cmov_single);
break;
case BoolTest::lt:
cmov_fp_cmp_fp_lt(op1, op2, dst, src, cmp_single, cmov_single);
break;
case BoolTest::gt:
cmov_fp_cmp_fp_gt(op1, op2, dst, src, cmp_single, cmov_single);
break;
default:
assert(false, "unsupported compare condition");
ShouldNotReachHere();
}
}
// Set dst to NaN if any NaN input.
void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2,
FLOAT_TYPE ft, bool is_min) {

View File

@ -132,6 +132,13 @@
FloatRegister op1, FloatRegister op2,
Register dst, Register src, bool is_single);
void enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
FloatRegister dst, FloatRegister src, bool is_single);
void enc_cmove_fp_cmp_fp(int cmpFlag, FloatRegister op1, FloatRegister op2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single);
void spill(Register r, bool is64, int offset) {
is64 ? sd(r, Address(sp, offset))
: sw(r, Address(sp, offset));

View File

@ -1233,7 +1233,119 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
bind(no_set);
}
// ----------- cmove, compare float -----------
// ----------- cmove float/double -----------
void MacroAssembler::cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bne(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
beq(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bgt(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bgtu(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
blt(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bltu(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bge(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bgeu(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
ble(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
Label no_set;
bleu(cmp1, cmp2, no_set);
if (is_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
// ----------- cmove, compare float/double -----------
//
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
// so, just list behaviour of unordered ones as follow.
@ -1391,6 +1503,148 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi
bind(no_set);
}
// ----------- cmove float/double, compare float/double -----------
// Move src to dst only if cmp1 == cmp2,
// otherwise leave dst unchanged, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 != cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 eq cmp2), dst, src
void MacroAssembler::cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 != cmp2, including the case of NaN
// not jump (i.e. move src to dst) if cmp1 == cmp2
float_bne(cmp1, cmp2, no_set);
} else {
double_bne(cmp1, cmp2, no_set);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
// Keep dst unchanged only if cmp1 == cmp2,
// otherwise move src to dst, including the case where one of them is NaN.
// Clarification:
// java code : cmp1 == cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 ne cmp2), dst, src
void MacroAssembler::cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 == cmp2
// not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
float_beq(cmp1, cmp2, no_set);
} else {
double_beq(cmp1, cmp2, no_set);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
// When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 < cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
// scenario 2:
// java code : cmp1 > cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
void MacroAssembler::cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 > cmp2
// not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
float_bgt(cmp1, cmp2, no_set);
} else {
double_bgt(cmp1, cmp2, no_set);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 < cmp2 or either is NaN
// not jump (i.e. move src to dst) if cmp1 >= cmp2
float_blt(cmp1, cmp2, no_set, false, true);
} else {
double_blt(cmp1, cmp2, no_set, false, true);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
// When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
// Clarification
// scenario 1:
// java code : cmp2 <= cmp1 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
// scenario 2:
// java code : cmp1 >= cmp2 ? dst : src
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
void MacroAssembler::cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 >= cmp2
// not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
float_bge(cmp1, cmp2, no_set);
} else {
double_bge(cmp1, cmp2, no_set);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
void MacroAssembler::cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2,
FloatRegister dst, FloatRegister src,
bool cmp_single, bool cmov_single) {
Label no_set;
if (cmp_single) {
// jump if cmp1 <= cmp2 or either is NaN
// not jump (i.e. move src to dst) if cmp1 > cmp2
float_ble(cmp1, cmp2, no_set, false, true);
} else {
double_ble(cmp1, cmp2, no_set, false, true);
}
if (cmov_single) {
fmv_s(dst, src);
} else {
fmv_d(dst, src);
}
bind(no_set);
}
// Float compare branch instructions
#define INSN(NAME, FLOATCMP, BRANCH) \

View File

@ -665,6 +665,24 @@ class MacroAssembler: public Assembler {
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
void cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
void cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
void cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
void cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
void cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
void cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
void cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
public:
// We try to follow risc-v asm menomics.
// But as we don't layout a reachable GOT,

View File

@ -1924,8 +1924,6 @@ bool Matcher::match_rule_supported(int opcode) {
case Op_SubHF:
return UseZfh;
case Op_CMoveF:
case Op_CMoveD:
case Op_CMoveP:
case Op_CMoveN:
return false;
@ -10466,6 +10464,286 @@ instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop)
ins_pipe(pipe_class_compare);
%}
// --------- CMoveF ---------
instruct cmovF_cmpI(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpI op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpI\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpU(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOpU cop) %{
match(Set dst (CMoveF (Binary cop (CmpU op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpU\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpL op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpL\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpUL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOpU cop) %{
match(Set dst (CMoveF (Binary cop (CmpUL op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpUL\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpF(fRegF dst, fRegF src, fRegF op1, fRegF op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpF\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
true /* cmp_single */, true /* cmov_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpD(fRegF dst, fRegF src, fRegD op1, fRegD op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpD\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
false /* cmp_single */, true /* cmov_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpN(fRegF dst, fRegF src, iRegN op1, iRegN op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpN op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpN\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovF_cmpP(fRegF dst, fRegF src, iRegP op1, iRegP op2, cmpOp cop) %{
match(Set dst (CMoveF (Binary cop (CmpP op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpP\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
// --------- CMoveD ---------
instruct cmovD_cmpI(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpI op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpI\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpU(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOpU cop) %{
match(Set dst (CMoveD (Binary cop (CmpU op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpU\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpL op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpL\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpUL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOpU cop) %{
match(Set dst (CMoveD (Binary cop (CmpUL op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpUL\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpF(fRegD dst, fRegD src, fRegF op1, fRegF op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpF\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
true /* cmp_single */, false /* cmov_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpD(fRegD dst, fRegD src, fRegD op1, fRegD op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpD\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
false /* cmp_single */, false /* cmov_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpN(fRegD dst, fRegD src, iRegN op1, iRegN op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpN op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpN\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
instruct cmovD_cmpP(fRegD dst, fRegD src, iRegP op1, iRegP op2, cmpOp cop) %{
match(Set dst (CMoveD (Binary cop (CmpP op1 op2)) (Binary dst src)));
ins_cost(ALU_COST + BRANCH_COST);
format %{
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpP\n\t"
%}
ins_encode %{
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
as_Register($op1$$reg), as_Register($op2$$reg),
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
%}
ins_pipe(pipe_class_compare);
%}
// ============================================================================
// Procedure Call/Return Instructions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,357 @@
/*
* Copyright (c) 2025, Rivos Inc. 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.c2.irTests;
import compiler.lib.ir_framework.*;
import java.util.Random;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
/*
* @test
* @summary Test conditional move + compare object.
* @requires vm.simpleArch == "riscv64"
* @library /test/lib /
* @run driver compiler.c2.irTests.TestScalarConditionalMoveCmpObj
*/
public class TestScalarConditionalMoveCmpObj {
final private static int SIZE = 1024;
private static final Random RANDOM = Utils.getRandomInstance();
public static void main(String[] args) {
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+UseCompressedOops");
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-UseCompressedOops");
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+UseCompressedOops");
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-UseCompressedOops");
}
// Object comparison
// O for I
private int cmoveOEQforI(Object a, Object b, int c, int d) {
return (a == b) ? c : d;
}
private int cmoveONEforI(Object a, Object b, int c, int d) {
return (a != b) ? c : d;
}
// O for L
private long cmoveOEQforL(Object a, Object b, long c, long d) {
return (a == b) ? c : d;
}
private long cmoveONEforL(Object a, Object b, long c, long d) {
return (a != b) ? c : d;
}
// O for F
private float cmoveOEQforF(Object a, Object b, float c, float d) {
return (a == b) ? c : d;
}
private float cmoveONEforF(Object a, Object b, float c, float d) {
return (a != b) ? c : d;
}
// O for D
private double cmoveOEQforD(Object a, Object b, double c, double d) {
return (a == b) ? c : d;
}
private double cmoveONEforD(Object a, Object b, double c, double d) {
return (a != b) ? c : d;
}
// Tests shows CMoveI is generated, so let @IR verify CMOVE_I.
//
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveOEQforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveONEforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
for (int i = 0; i < a.length; i++) {
int cc = c[i];
int dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
}
}
// So far, CMoveL is not guaranteed to be generated, so @IR not verify CMOVE_L.
// TODO: enable CMOVE_L verification when it's guaranteed to generate CMOVE_L.
//
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
private static void testCMoveOEQforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
// applyIf = {"UseCompressedOops", "false"})
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
// applyIf = {"UseCompressedOops", "true"})
private static void testCMoveONEforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
for (int i = 0; i < a.length; i++) {
long cc = c[i];
long dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveOEQforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveONEforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
for (int i = 0; i < a.length; i++) {
float cc = c[i];
float dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveOEQforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] == b[i]) ? cc : dd;
}
}
@Test
@IR(failOn = {IRNode.STORE_VECTOR})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
applyIf = {"UseCompressedOops", "false"})
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
applyIf = {"UseCompressedOops", "true"})
private static void testCMoveONEforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
for (int i = 0; i < a.length; i++) {
double cc = c[i];
double dd = d[i];
r2[i] = cc + dd;
r[i] = (a[i] != b[i]) ? cc : dd;
}
}
@Warmup(0)
@Run(test = {// Object
"testCMoveOEQforI",
"testCMoveONEforI",
"testCMoveOEQforL",
"testCMoveONEforL",
"testCMoveOEQforF",
"testCMoveONEforF",
"testCMoveOEQforD",
"testCMoveONEforD",
})
private void testCMove_runner_two() {
Object[] aO = new Object[SIZE];
Object[] bO = new Object[SIZE];
int[] cI = new int[SIZE];
int[] dI = new int[SIZE];
int[] rI = new int[SIZE];
long[] cL = new long[SIZE];
long[] dL = new long[SIZE];
long[] rL = new long[SIZE];
float[] cF = new float[SIZE];
float[] dF = new float[SIZE];
float[] rF = new float[SIZE];
double[] cD = new double[SIZE];
double[] dD = new double[SIZE];
double[] rD = new double[SIZE];
init(aO);
shuffle(aO, bO);
init(cL);
init(dL);
init(cF);
init(dF);
init(cD);
init(dD);
testCMoveOEQforI(aO, bO, cI, dI, rI, rI);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rI[i], cmoveOEQforI(aO[i], bO[i], cI[i], dI[i]));
}
testCMoveONEforI(aO, bO, cI, dI, rI, rI);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rI[i], cmoveONEforI(aO[i], bO[i], cI[i], dI[i]));
}
testCMoveOEQforL(aO, bO, cL, dL, rL, rL);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rL[i], cmoveOEQforL(aO[i], bO[i], cL[i], dL[i]));
}
testCMoveONEforL(aO, bO, cL, dL, rL, rL);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rL[i], cmoveONEforL(aO[i], bO[i], cL[i], dL[i]));
}
testCMoveOEQforF(aO, bO, cF, dF, rF, rF);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rF[i], cmoveOEQforF(aO[i], bO[i], cF[i], dF[i]));
}
testCMoveONEforF(aO, bO, cF, dF, rF, rF);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rF[i], cmoveONEforF(aO[i], bO[i], cF[i], dF[i]));
}
testCMoveOEQforD(aO, bO, cD, dD, rD, rD);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rD[i], cmoveOEQforD(aO[i], bO[i], cD[i], dD[i]));
}
testCMoveONEforD(aO, bO, cD, dD, rD, rD);
for (int i = 0; i < SIZE; i++) {
Asserts.assertEquals(rD[i], cmoveONEforD(aO[i], bO[i], cD[i], dD[i]));
}
}
private static void init(Object[] a) {
for (int i = 0; i < SIZE; i++) {
a[i] = new Object();
}
}
private static void shuffle(Object[] a, Object[] b) {
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
Random rand = new Random();
for (int i = 0; i < SIZE; i++) {
if (rand.nextInt(5) == 0) {
Object t = b[i];
b[i] = b[SIZE-1-i];
b[SIZE-1-i] = t;
}
}
}
private static void init(int[] a) {
for (int i = 0; i < SIZE; i++) {
a[i] = RANDOM.nextInt();
}
}
private static void init(long[] a) {
for (int i = 0; i < SIZE; i++) {
a[i] = RANDOM.nextLong();
}
}
private static void init(float[] a) {
for (int i = 0; i < SIZE; i++) {
a[i] = switch(RANDOM.nextInt() % 20) {
case 0 -> Float.NaN;
case 1 -> 0;
case 2 -> 1;
case 3 -> Float.POSITIVE_INFINITY;
case 4 -> Float.NEGATIVE_INFINITY;
case 5 -> Float.MAX_VALUE;
case 6 -> Float.MIN_VALUE;
case 7, 8, 9 -> RANDOM.nextFloat();
default -> Float.intBitsToFloat(RANDOM.nextInt());
};
}
}
private static void init(double[] a) {
for (int i = 0; i < SIZE; i++) {
a[i] = switch(RANDOM.nextInt() % 20) {
case 0 -> Double.NaN;
case 1 -> 0;
case 2 -> 1;
case 3 -> Double.POSITIVE_INFINITY;
case 4 -> Double.NEGATIVE_INFINITY;
case 5 -> Double.MAX_VALUE;
case 6 -> Double.MIN_VALUE;
case 7, 8, 9 -> RANDOM.nextDouble();
default -> Double.longBitsToDouble(RANDOM.nextLong());
};
}
}
}

View File

@ -545,11 +545,36 @@ public class IRNode {
trapNodes(CLASS_CHECK_TRAP, "class_check");
}
public static final String CMOVE_F = PREFIX + "CMOVE_F" + POSTFIX;
static {
beforeMatchingNameRegex(CMOVE_F, "CMoveF");
}
public static final String CMOVE_D = PREFIX + "CMOVE_D" + POSTFIX;
static {
beforeMatchingNameRegex(CMOVE_D, "CMoveD");
}
public static final String CMOVE_I = PREFIX + "CMOVE_I" + POSTFIX;
static {
beforeMatchingNameRegex(CMOVE_I, "CMoveI");
}
public static final String CMOVE_L = PREFIX + "CMOVE_L" + POSTFIX;
static {
beforeMatchingNameRegex(CMOVE_L, "CMoveL");
}
public static final String CMP_F = PREFIX + "CMP_F" + POSTFIX;
static {
beforeMatchingNameRegex(CMP_F, "CmpF");
}
public static final String CMP_D = PREFIX + "CMP_D" + POSTFIX;
static {
beforeMatchingNameRegex(CMP_D, "CmpD");
}
public static final String CMP_I = PREFIX + "CMP_I" + POSTFIX;
static {
beforeMatchingNameRegex(CMP_I, "CmpI");
@ -585,6 +610,11 @@ public class IRNode {
beforeMatchingNameRegex(CMP_P, "CmpP");
}
public static final String CMP_N = PREFIX + "CMP_N" + POSTFIX;
static {
beforeMatchingNameRegex(CMP_N, "CmpN");
}
public static final String CMP_LT_MASK = PREFIX + "CMP_LT_MASK" + POSTFIX;
static {
beforeMatchingNameRegex(CMP_LT_MASK, "CmpLTMask");

View File

@ -44,12 +44,8 @@ public class ClassComparison {
Class[] c2;
int[] res;
long[] resLong;
Object[] resObject;
Object ro1;
Object ro2;
Object[] resClass;
Class rc1;
Class rc2;
float[] resFloat;
double[] resDouble;
@Setup
public void setup() {
@ -58,12 +54,8 @@ public class ClassComparison {
c2 = new Class[INVOCATIONS];
res = new int[INVOCATIONS];
resLong = new long[INVOCATIONS];
resObject = new Object[INVOCATIONS];
ro1 = new Object();
ro2 = new Object();
resClass = new Class[INVOCATIONS];
rc1 = Float.class;
rc2 = Double.class;
resFloat = new float[INVOCATIONS];
resDouble = new double[INVOCATIONS];
for (int i = 0; i < INVOCATIONS; i++) {
c1[i] = random.nextBoolean() ? Float.class : Double.class;
}
@ -86,6 +78,7 @@ public class ClassComparison {
}
}
@Benchmark
public void equalClassResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (c1[i] == c2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -98,4 +91,32 @@ public class ClassComparison {
resLong[i] = (c1[i] != c2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void equalClassResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (c1[i] == c2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualClassResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (c1[i] != c2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void equalClassResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (c1[i] == c2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualClassResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (c1[i] != c2[i]) ? 0.1 : 0.2;
}
}
}

View File

@ -37,34 +37,18 @@ import java.util.random.RandomGenerator;
public class FPComparison {
static final int INVOCATIONS = 1024;
float[] f1;
double[] d1;
float[] f2;
double[] d2;
int[] res;
long[] resLong;
Object[] resObject;
Object ro1;
Object ro2;
Class[] resClass;
Class rc1;
Class rc2;
static final float[] f1 = new float[INVOCATIONS];
static final double[] d1 = new double[INVOCATIONS];
static final float[] f2 = new float[INVOCATIONS];
static final double[] d2 = new double[INVOCATIONS];
static final int[] res = new int[INVOCATIONS];;
static final long[] resLong = new long[INVOCATIONS];
static final float[] resFloat = new float[INVOCATIONS];
static final double[] resDouble = new double[INVOCATIONS];
@Setup
public void setup() {
var random = RandomGenerator.getDefault();
f1 = new float[INVOCATIONS];
d1 = new double[INVOCATIONS];
f2 = new float[INVOCATIONS];
d2 = new double[INVOCATIONS];
res = new int[INVOCATIONS];
resLong = new long[INVOCATIONS];
resObject = new Object[INVOCATIONS];
ro1 = new Object();
ro2 = new Object();
resClass = new Class[INVOCATIONS];
rc1 = Float.class;
rc2 = Double.class;
for (int i = 0; i < INVOCATIONS; i++) {
int type = random.nextInt(5);
if (type == 1) {
@ -274,4 +258,148 @@ public class FPComparison {
resLong[i] = (d1[i] >= d2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
// --------- result: float ---------
@Benchmark
public void equalFloatResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (f1[i] == f2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void equalDoubleResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (d1[i] == d2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessFloatResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (f1[i] < f2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessDoubleResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (d1[i] < d2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualFloatResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (f1[i] <= f2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualDoubleResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (d1[i] <= d2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterFloatResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (f1[i] > f2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterDoubleResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (d1[i] > d2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualFloatResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (f1[i] >= f2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualDoubleResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (d1[i] >= d2[i]) ? 0.1f : 0.2f;
}
}
// --------- result: double ---------
@Benchmark
public void equalFloatResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (f1[i] == f2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void equalDoubleResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (d1[i] == d2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessFloatResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (f1[i] < f2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessDoubleResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (d1[i] < d2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualFloatResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (f1[i] <= f2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualDoubleResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (d1[i] <= d2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterFloatResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (f1[i] > f2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterDoubleResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (d1[i] > d2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualFloatResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (f1[i] >= f2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualDoubleResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (d1[i] >= d2[i]) ? 0.1 : 0.2;
}
}
}

View File

@ -42,12 +42,8 @@ public class IntegerComparison {
int[] i2;
int[] res;
long[] resLong;
Object[] resObject;
Object ro1;
Object ro2;
Object[] resClass;
Class rc1;
Class rc2;
float[] resFloat;
double[] resDouble;
@Setup
public void setup() {
@ -56,18 +52,17 @@ public class IntegerComparison {
i2 = new int[INVOCATIONS];
res = new int[INVOCATIONS];
resLong = new long[INVOCATIONS];
resObject = new Object[INVOCATIONS];
ro1 = new Object();
ro2 = new Object();
resClass = new Class[INVOCATIONS];
rc1 = Float.class;
rc2 = Double.class;
resFloat = new float[INVOCATIONS];
resDouble = new double[INVOCATIONS];
for (int i = 0; i < INVOCATIONS; i++) {
i1[i] = random.nextInt(INVOCATIONS);
i2[i] = random.nextInt(INVOCATIONS);
}
}
// --------- result: int ---------
// Signed comparison
@Benchmark
public void equalInteger() {
for (int i = 0; i < INVOCATIONS; i++) {
@ -110,8 +105,55 @@ public class IntegerComparison {
}
}
// --------- result: long ---------
// Unsigned comparison
@Benchmark
public void equalIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 1 : 2;
}
}
@Benchmark
public void notEqualIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 1 : 2;
}
}
@Benchmark
public void lessIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 1 : 2;
}
}
@Benchmark
public void lessEqualIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 1 : 2;
}
}
@Benchmark
public void greaterIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 1 : 2;
}
}
@Benchmark
public void greaterEqualIntegerUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 1 : 2;
}
}
// --------- result: long ---------
// Signed comparison
@Benchmark
public void equalIntegerResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (i1[i] == i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -125,6 +167,7 @@ public class IntegerComparison {
}
}
@Benchmark
public void lessIntegerResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (i1[i] < i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -138,6 +181,7 @@ public class IntegerComparison {
}
}
@Benchmark
public void greaterIntegerResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (i1[i] > i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -150,4 +194,226 @@ public class IntegerComparison {
resLong[i] = (i1[i] >= i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
// Unsigned comparison
@Benchmark
public void equalIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void notEqualIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void lessIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void lessEqualIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void greaterIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void greaterEqualIntegerUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
// --------- result: float ---------
// Signed comparison
@Benchmark
public void equalIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] == i2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] != i2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] < i2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] <= i2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] > i2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualIntegerResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (i1[i] >= i2[i]) ? 0.1f : 0.2f;
}
}
// Unsigned comparison
@Benchmark
public void equalIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualIntegerUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 0.1f : 0.2f;
}
}
// --------- result: double ---------
// Signed comparison
@Benchmark
public void equalIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] == i2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] != i2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] < i2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] <= i2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] > i2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualIntegerResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (i1[i] >= i2[i]) ? 0.1 : 0.2;
}
}
// Unsigned comparison
@Benchmark
public void equalIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void lessIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualIntegerUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 0.1 : 0.2;
}
}
}

View File

@ -41,12 +41,8 @@ public class LongComparison {
long[] l2;
int[] res;
long[] resLong;
Object[] resObject;
Object ro1;
Object ro2;
Object[] resClass;
Class rc1;
Class rc2;
float[] resFloat;
double[] resDouble;
@Setup
public void setup() {
@ -55,18 +51,17 @@ public class LongComparison {
l2 = new long[INVOCATIONS];
res = new int[INVOCATIONS];
resLong = new long[INVOCATIONS];
resObject = new Object[INVOCATIONS];
ro1 = new Object();
ro2 = new Object();
resClass = new Class[INVOCATIONS];
rc1 = Float.class;
rc2 = Double.class;
resFloat = new float[INVOCATIONS];
resDouble = new double[INVOCATIONS];
for (int i = 0; i < INVOCATIONS; i++) {
l1[i] = random.nextLong(INVOCATIONS);
l2[i] = random.nextLong(INVOCATIONS);
}
}
// --------- result: int ---------
// Signed comparison
@Benchmark
public void equalLong() {
for (int i = 0; i < INVOCATIONS; i++) {
@ -109,8 +104,54 @@ public class LongComparison {
}
}
// --------- result: long ---------
// Unsigned comparison
@Benchmark
public void equalLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 1 : 2;
}
}
@Benchmark
public void notEqualLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 1 : 2;
}
}
@Benchmark
public void lessLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 1 : 2;
}
}
@Benchmark
public void lessEqualLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 1 : 2;
}
}
@Benchmark
public void greaterLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 1 : 2;
}
}
@Benchmark
public void greaterEqualLongUnsigned() {
for (int i = 0; i < INVOCATIONS; i++) {
res[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 1 : 2;
}
}
// --------- result: long ---------
// Signed comparison
@Benchmark
public void equalLongResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (l1[i] == l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -124,6 +165,7 @@ public class LongComparison {
}
}
@Benchmark
public void lessLongResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (l1[i] < l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -137,6 +179,7 @@ public class LongComparison {
}
}
@Benchmark
public void greaterLongResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (l1[i] > l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -149,4 +192,226 @@ public class LongComparison {
resLong[i] = (l1[i] >= l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
// Unsigned comparison
@Benchmark
public void equalLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void notEqualLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void lessLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void lessEqualLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void greaterLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void greaterEqualLongUnsignedResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
// --------- result: float ---------
// Signed comparison
@Benchmark
public void equalLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] == l2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] != l2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] < l2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] <= l2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] > l2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualLongResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (l1[i] >= l2[i]) ? 0.1f : 0.2f;
}
}
// Unsigned comparison
@Benchmark
public void equalLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void lessEqualLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 0.1f : 0.2f;
}
}
@Benchmark
public void greaterEqualLongUnsignedResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 0.1f : 0.2f;
}
}
// --------- result: double ---------
// Signed comparison
@Benchmark
public void equalLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] == l2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] != l2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] < l2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] <= l2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] > l2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualLongResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (l1[i] >= l2[i]) ? 0.1 : 0.2;
}
}
// Unsigned comparison
@Benchmark
public void equalLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void lessLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void lessEqualLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 0.1 : 0.2;
}
}
@Benchmark
public void greaterEqualLongUnsignedResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 0.1 : 0.2;
}
}
}

View File

@ -44,12 +44,8 @@ public class PointerComparison {
Object[] o2;
int[] res;
long[] resLong;
Object[] resObject;
Object ro1;
Object ro2;
Object[] resClass;
Class rc1;
Class rc2;
float[] resFloat;
double[] resDouble;
@Setup
public void setup() {
@ -58,12 +54,8 @@ public class PointerComparison {
o2 = new Object[INVOCATIONS];
res = new int[INVOCATIONS];
resLong = new long[INVOCATIONS];
resObject = new Object[INVOCATIONS];
ro1 = new Object();
ro2 = new Object();
resClass = new Class[INVOCATIONS];
rc1 = Float.class;
rc2 = Double.class;
resFloat = new float[INVOCATIONS];
resDouble = new double[INVOCATIONS];
for (int i = 0; i < INVOCATIONS; i++) {
o1[i] = new Object();
}
@ -86,6 +78,7 @@ public class PointerComparison {
}
}
@Benchmark
public void equalObjectResLong() {
for (int i = 0; i < INVOCATIONS; i++) {
resLong[i] = (o1[i] == o2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
@ -98,4 +91,32 @@ public class PointerComparison {
resLong[i] = (o1[i] != o2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@Benchmark
public void equalObjecResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (o1[i] == o2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void notEqualObjecResFloat() {
for (int i = 0; i < INVOCATIONS; i++) {
resFloat[i] = (o1[i] != o2[i]) ? 0.1f : 0.2f;
}
}
@Benchmark
public void equalObjecResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (o1[i] == o2[i]) ? 0.1 : 0.2;
}
}
@Benchmark
public void notEqualObjecResDouble() {
for (int i = 0; i < INVOCATIONS; i++) {
resDouble[i] = (o1[i] != o2[i]) ? 0.1 : 0.2;
}
}
}