diff --git a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp index 0fbc2ef141e8b..49eae1cc438a1 100644 --- a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp @@ -204,4 +204,9 @@ static bool is_feat_fp16_supported() { return (VM_Version::supports_fphp() && VM_Version::supports_asimdhp()); } + + static bool supports_vector_different_use_def_size() { + return false; + } + #endif // CPU_AARCH64_MATCHER_AARCH64_HPP diff --git a/src/hotspot/cpu/arm/matcher_arm.hpp b/src/hotspot/cpu/arm/matcher_arm.hpp index 66fe8ac330eb5..28e9caf1ab084 100644 --- a/src/hotspot/cpu/arm/matcher_arm.hpp +++ b/src/hotspot/cpu/arm/matcher_arm.hpp @@ -193,4 +193,8 @@ return false; } + static bool supports_vector_different_use_def_size() { + return false; + } + #endif // CPU_ARM_MATCHER_ARM_HPP diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index aad41fb7b1cf0..987b959aa3b43 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -203,4 +203,8 @@ return false; } + static bool supports_vector_different_use_def_size() { + return false; + } + #endif // CPU_PPC_MATCHER_PPC_HPP diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 154b62db47fdf..d18dcc90cf51e 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2067,6 +2067,87 @@ 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, Register tmp1, Register tmp2, + 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, tmp1, tmp2, dst, src, is_single); + break; + case BoolTest::ne: + cmov_fp_ne(op1, op2, tmp1, tmp2, dst, src, is_single); + break; + case BoolTest::le: + if (is_unsigned) { + cmov_fp_leu(op1, op2, tmp1, tmp2, dst, src, is_single); + } else { + cmov_fp_le(op1, op2, tmp1, tmp2, dst, src, is_single); + } + break; + case BoolTest::ge: + if (is_unsigned) { + cmov_fp_geu(op1, op2, tmp1, tmp2, dst, src, is_single); + } else { + cmov_fp_ge(op1, op2, tmp1, tmp2, dst, src, is_single); + } + break; + case BoolTest::lt: + if (is_unsigned) { + cmov_fp_ltu(op1, op2, tmp1, tmp2, dst, src, is_single); + } else { + cmov_fp_lt(op1, op2, tmp1, tmp2, dst, src, is_single); + } + break; + case BoolTest::gt: + if (is_unsigned) { + cmov_fp_gtu(op1, op2, tmp1, tmp2, dst, src, is_single); + } else { + cmov_fp_gt(op1, op2, tmp1, tmp2, 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, + Register tmp1, Register tmp2, + 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, tmp1, tmp2, dst, src, cmp_single, cmov_single); + break; + case BoolTest::ne: + cmov_fp_cmp_fp_ne(op1, op2, tmp1, tmp2, dst, src, cmp_single, cmov_single); + break; + case BoolTest::le: + cmov_fp_cmp_fp_le(op1, op2, tmp1, tmp2, dst, src, cmp_single, cmov_single); + break; + case BoolTest::ge: + assert(false, "Should go to BoolTest::le case"); + ShouldNotReachHere(); + break; + case BoolTest::lt: + cmov_fp_cmp_fp_lt(op1, op2, tmp1, tmp2, dst, src, cmp_single, cmov_single); + break; + case BoolTest::gt: + assert(false, "Should go to BoolTest::lt case"); + ShouldNotReachHere(); + 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) { diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 2d5339dc153c8..6ed1bce63441e 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -132,6 +132,16 @@ FloatRegister op1, FloatRegister op2, Register dst, Register src, bool is_single); + void enc_cmove_fp_cmp(int cmpFlag, + Register op1, Register op2, Register tmp1, Register tmp2, + FloatRegister dst, FloatRegister src, bool is_single); + + void enc_cmove_fp_cmp_fp(int cmpFlag, + FloatRegister op1, FloatRegister op2, + Register tmp1, Register tmp2, + 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)); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 700e42e6194ce..871c942e5ed83 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1240,7 +1240,309 @@ 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + xorr(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + xorr(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + slt(t0, cmp2, cmp1); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + sltu(t0, cmp2, cmp1); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + slt(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + sltu(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + slt(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + sltu(t0, cmp1, cmp2); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + slt(t0, cmp2, cmp1); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single) { + if (UseZicond) { + sltu(t0, cmp2, cmp1); + if (is_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0, tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (is_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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. @@ -1397,6 +1699,205 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi mv(dst, src); 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, + Register tmpDst, Register tmpSrc, + FloatRegister dst, FloatRegister src, + bool cmp_single, bool cmov_single) { + if (UseZicond) { + if (cmp_single) { + feq_s(t0, cmp1, cmp2); + } else { + feq_d(t0, cmp1, cmp2); + } + if (cmov_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_nez(tmpDst, tmpDst, t0); + czero_eqz(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (cmov_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, + Register tmpDst, Register tmpSrc, + FloatRegister dst, FloatRegister src, + bool cmp_single, bool cmov_single) { + if (UseZicond) { + if (cmp_single) { + feq_s(t0, cmp1, cmp2); + } else { + feq_d(t0, cmp1, cmp2); + } + if (cmov_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (cmov_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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, + Register tmpDst, Register tmpSrc, + FloatRegister dst, FloatRegister src, + bool cmp_single, bool cmov_single) { + if (UseZicond) { + if (cmp_single) { + flt_s(t0, cmp2, cmp1); + } else { + flt_d(t0, cmp2, cmp1); + } + if (cmov_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (cmov_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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); +} + +// 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, + Register tmpDst, Register tmpSrc, + FloatRegister dst, FloatRegister src, + bool cmp_single, bool cmov_single) { + if (UseZicond) { + if (cmp_single) { + fle_s(t0, cmp2, cmp1); + } else { + fle_d(t0, cmp2, cmp1); + } + if (cmov_single) { + fmv_x_w(tmpDst, dst); + fmv_x_w(tmpSrc, src); + } else { + fmv_x_d(tmpDst, dst); + fmv_x_d(tmpSrc, src); + } + czero_eqz(tmpDst, tmpDst, t0); + czero_nez(t0 , tmpSrc, t0); + orr(tmpDst, tmpDst, t0); + if (cmov_single) { + fmv_w_x(dst, tmpDst); + } else { + fmv_d_x(dst, tmpDst); + } + return; + } + 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); +} // Float compare branch instructions diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 9e713e9027022..2c6e128cdc9ac 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -664,6 +664,22 @@ 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, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_ne(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_le(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_leu(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_ge(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_geu(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_lt(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_ltu(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_gt(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + void cmov_fp_gtu(Register cmp1, Register cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool is_single); + + void cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single); + void cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single); + void cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register tmpDst, Register tmpSrc, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single); + void cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register tmpDst, Register tmpSrc, 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, diff --git a/src/hotspot/cpu/riscv/matcher_riscv.hpp b/src/hotspot/cpu/riscv/matcher_riscv.hpp index 1b490a07f92a6..f6b99af45b8bd 100644 --- a/src/hotspot/cpu/riscv/matcher_riscv.hpp +++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp @@ -199,4 +199,8 @@ return false; } + static bool supports_vector_different_use_def_size() { + return true; + } + #endif // CPU_RISCV_MATCHER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 83c59af9113e9..7d4a95d45ba05 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1933,8 +1933,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; @@ -10464,6 +10462,321 @@ 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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpI op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpI\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpI"); + __ enc_cmove_fp_cmp($cop$$cmpcode, + as_Register($op1$$reg), as_Register($op2$$reg), as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOpU cop) %{ + match(Set dst (CMoveF (Binary cop (CmpU op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpU\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpU"); + __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpL op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpL\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpL"); + __ enc_cmove_fp_cmp($cop$$cmpcode, + as_Register($op1$$reg), as_Register($op2$$reg), as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOpU cop) %{ + match(Set dst (CMoveF (Binary cop (CmpUL op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpUL\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpUL"); + __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpF\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpF"); + __ enc_cmove_fp_cmp_fp($cop$$cmpcode, + as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), + as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpD\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpD"); + __ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask, + as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), + as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpN op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpN\n\t" + %} + + ins_encode %{ + // __ stop("cmovF_cmpN"); + __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($tmp1$$reg), as_Register($tmp2$$reg), + as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */); + %} + + ins_pipe(pipe_class_compare); +%} + +instruct cmovF_cmpP(fRegF dst, fRegF src, iRegN op1, iRegN op2, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveF (Binary cop (CmpP op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ + "CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpP\n\t" + %} + + ins_encode %{ + __ stop("cmovF_cmpP"); + __ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpI op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOpU cop) %{ + match(Set dst (CMoveD (Binary cop (CmpU op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpL op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOpU cop) %{ + match(Set dst (CMoveD (Binary cop (CmpUL op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$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, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpN op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$reg), + as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */); + %} + + ins_pipe(pipe_class_compare); +%} + +instruct cmovD_cmpP(fRegD dst, fRegD src, iRegN op1, iRegN op2, iRegI tmp1, iRegI tmp2, cmpOp cop) %{ + match(Set dst (CMoveD (Binary cop (CmpP op1 op2)) (Binary dst src))); + effect(TEMP tmp1, TEMP tmp2); + 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_Register($tmp1$$reg), as_Register($tmp2$$reg), + as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */); + %} + + ins_pipe(pipe_class_compare); +%} // ============================================================================ // Procedure Call/Return Instructions diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index fe323474d60de..196c6d3f4c48e 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -230,6 +230,7 @@ instruct vstoremask(vReg dst, vRegMask_V0 v0, immI size) %{ instruct vmaskcmp(vRegMask dst, vReg src1, vReg src2, immI cond) %{ predicate(Matcher::vector_element_basic_type(n) == T_BYTE || + Matcher::vector_element_basic_type(n) == T_CHAR || Matcher::vector_element_basic_type(n) == T_SHORT || Matcher::vector_element_basic_type(n) == T_INT || Matcher::vector_element_basic_type(n) == T_LONG); @@ -247,6 +248,7 @@ instruct vmaskcmp(vRegMask dst, vReg src1, vReg src2, immI cond) %{ instruct vmaskcmp_masked(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask_V0 v0) %{ predicate(Matcher::vector_element_basic_type(n) == T_BYTE || + Matcher::vector_element_basic_type(n) == T_CHAR || Matcher::vector_element_basic_type(n) == T_SHORT || Matcher::vector_element_basic_type(n) == T_INT || Matcher::vector_element_basic_type(n) == T_LONG); diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index e4c277c63a8b9..8ab5587aaba20 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -196,4 +196,8 @@ return false; } + static bool supports_vector_different_use_def_size() { + return false; + } + #endif // CPU_S390_MATCHER_S390_HPP diff --git a/src/hotspot/cpu/x86/matcher_x86.hpp b/src/hotspot/cpu/x86/matcher_x86.hpp index 41486c244b247..d12cb7cb84276 100644 --- a/src/hotspot/cpu/x86/matcher_x86.hpp +++ b/src/hotspot/cpu/x86/matcher_x86.hpp @@ -236,4 +236,8 @@ } } + static bool supports_vector_different_use_def_size() { + return false; + } + #endif // CPU_X86_MATCHER_X86_HPP diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index cc4a94aa05460..dea8be591d7ac 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2331,8 +2331,14 @@ bool SuperWord::is_velt_basic_type_compatible_use_def(Node* use, Node* def) cons type2aelembytes(use_bt) == 4; } - // Default case: input size of use equals output size of def. - return type2aelembytes(use_bt) == type2aelembytes(def_bt); + // Input size of use equals output size of def + if (type2aelembytes(use_bt) == type2aelembytes(def_bt)) { + return true; + } else if (VectorNode::is_different_use_def_size_supported()) { + return use->is_CMove() && def->is_Bool(); + } + + return false; } // Return nullptr if success, else failure message diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 6ae8bbe8aa0af..b6480c3a9652a 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -406,6 +406,10 @@ bool VectorNode::is_populate_index_supported(BasicType bt) { return Matcher::match_rule_supported_vector(Op_PopulateIndex, vlen, bt); } +bool VectorNode::is_different_use_def_size_supported() { + return Matcher::supports_vector_different_use_def_size(); +} + bool VectorNode::is_shift_opcode(int opc) { switch (opc) { case Op_LShiftI: @@ -2302,6 +2306,7 @@ Node* VectorBlendNode::Identity(PhaseGVN* phase) { } return this; } + static bool is_replicate_uint_constant(const Node* n) { return n->Opcode() == Op_Replicate && n->in(1)->is_Con() && diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 427aeff53fcf9..aba825081474e 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -110,6 +110,9 @@ class VectorNode : public TypeNode { static bool is_vector_rotate_supported(int opc, uint vlen, BasicType bt); static bool is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate); static bool is_populate_index_supported(BasicType bt); + // Return true if every bit in this vector is 1, e.g. based on the comparison + // result of 2 floats, set a double result. + static bool is_different_use_def_size_supported(); // Return true if every bit in this vector is 1. static bool is_all_ones_vector(Node* n); // Return true if every bit in this vector is 0. diff --git a/src/hotspot/share/opto/vtransform.cpp b/src/hotspot/share/opto/vtransform.cpp index 46e8f43cb657d..40c5206bccb95 100644 --- a/src/hotspot/share/opto/vtransform.cpp +++ b/src/hotspot/share/opto/vtransform.cpp @@ -1421,8 +1421,9 @@ void VTransformReinterpretVectorNode::print_spec() const { void VTransformBoolVectorNode::print_spec() const { VTransformVectorNode::print_spec(); - const BoolTest bt(_test._mask); - tty->print(" test="); + BoolTest::mask m = BoolTest::mask(_test._mask & ~BoolTest::unsigned_compare); + const BoolTest bt(m); + tty->print(" test=%s", m == _test._mask ? "" : "unsigned "); bt.dump_on(tty); } #endif diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestScalarConditionalMove.java b/test/hotspot/jtreg/compiler/c2/irTests/TestScalarConditionalMove.java new file mode 100644 index 0000000000000..c9a5c887dcda2 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestScalarConditionalMove.java @@ -0,0 +1,3072 @@ +/* + * Copyright (c) 2022, 2025, Arm Limited. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * 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. + * @requires vm.simpleArch == "riscv64" + * @library /test/lib / + * @run driver compiler.c2.irTests.TestScalarConditionalMove + */ + +public class TestScalarConditionalMove { + 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"); + TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders"); + } + + // Compare 2 values, and pick one of them + private float cmoveFloatGT(float a, float b) { + return (a > b) ? a : b; + } + + private float cmoveFloatGTSwap(float a, float b) { + return (b > a) ? a : b; + } + + private float cmoveFloatLT(float a, float b) { + return (a < b) ? a : b; + } + + private float cmoveFloatLTSwap(float a, float b) { + return (b < a) ? a : b; + } + + private float cmoveFloatEQ(float a, float b) { + return (a == b) ? a : b; + } + + private double cmoveDoubleLE(double a, double b) { + return (a <= b) ? a : b; + } + + private double cmoveDoubleLESwap(double a, double b) { + return (b <= a) ? a : b; + } + + private double cmoveDoubleGE(double a, double b) { + return (a >= b) ? a : b; + } + + private double cmoveDoubleGESwap(double a, double b) { + return (b >= a) ? a : b; + } + + private double cmoveDoubleNE(double a, double b) { + return (a != b) ? a : b; + } + + // Extensions: compare 2 values, and pick from 2 consts + private float cmoveFGTforFConst(float a, float b) { + return (a > b) ? 0.1f : -0.1f; + } + + private float cmoveFGEforFConst(float a, float b) { + return (a >= b) ? 0.1f : -0.1f; + } + + private float cmoveFLTforFConst(float a, float b) { + return (a < b) ? 0.1f : -0.1f; + } + + private float cmoveFLEforFConst(float a, float b) { + return (a <= b) ? 0.1f : -0.1f; + } + + private float cmoveFEQforFConst(float a, float b) { + return (a == b) ? 0.1f : -0.1f; + } + + private float cmoveFNEQforFConst(float a, float b) { + return (a != b) ? 0.1f : -0.1f; + } + + private double cmoveDGTforDConst(double a, double b) { + return (a > b) ? 0.1 : -0.1; + } + + private double cmoveDGEforDConst(double a, double b) { + return (a >= b) ? 0.1 : -0.1; + } + + private double cmoveDLTforDConst(double a, double b) { + return (a < b) ? 0.1 : -0.1; + } + + private double cmoveDLEforDConst(double a, double b) { + return (a <= b) ? 0.1 : -0.1; + } + + private double cmoveDEQforDConst(double a, double b) { + return (a == b) ? 0.1 : -0.1; + } + + private double cmoveDNEQforDConst(double a, double b) { + return (a != b) ? 0.1 : -0.1; + } + + // Extension: Compare 2 ILFD values, and pick from 2 ILFD values + // Signed comparison: I/L + // I for I + private int cmoveIEQforI(int a, int b, int c, int d) { + return (a == b) ? c : d; + } + + private int cmoveINEforI(int a, int b, int c, int d) { + return (a != b) ? c : d; + } + + private int cmoveIGTforI(int a, int b, int c, int d) { + return (a > b) ? c : d; + } + + private int cmoveIGEforI(int a, int b, int c, int d) { + return (a >= b) ? c : d; + } + + private int cmoveILTforI(int a, int b, int c, int d) { + return (a < b) ? c : d; + } + + private int cmoveILEforI(int a, int b, int c, int d) { + return (a <= b) ? c : d; + } + + // I for L + private long cmoveIEQforL(int a, int b, long c, long d) { + return (a == b) ? c : d; + } + + private long cmoveINEforL(int a, int b, long c, long d) { + return (a != b) ? c : d; + } + + private long cmoveIGTforL(int a, int b, long c, long d) { + return (a > b) ? c : d; + } + + private long cmoveIGEforL(int a, int b, long c, long d) { + return (a >= b) ? c : d; + } + + private long cmoveILTforL(int a, int b, long c, long d) { + return (a < b) ? c : d; + } + + private long cmoveILEforL(int a, int b, long c, long d) { + return (a <= b) ? c : d; + } + + // I for F + private float cmoveIEQforF(int a, int b, float c, float d) { + return (a == b) ? c : d; + } + + private float cmoveINEforF(int a, int b, float c, float d) { + return (a != b) ? c : d; + } + + private float cmoveIGTforF(int a, int b, float c, float d) { + return (a > b) ? c : d; + } + + private float cmoveIGEforF(int a, int b, float c, float d) { + return (a >= b) ? c : d; + } + + private float cmoveILTforF(int a, int b, float c, float d) { + return (a < b) ? c : d; + } + + private float cmoveILEforF(int a, int b, float c, float d) { + return (a <= b) ? c : d; + } + + // I for D + private double cmoveIEQforD(int a, int b, double c, double d) { + return (a == b) ? c : d; + } + + private double cmoveINEforD(int a, int b, double c, double d) { + return (a != b) ? c : d; + } + + private double cmoveIGTforD(int a, int b, double c, double d) { + return (a > b) ? c : d; + } + + private double cmoveIGEforD(int a, int b, double c, double d) { + return (a >= b) ? c : d; + } + + private double cmoveILTforD(int a, int b, double c, double d) { + return (a < b) ? c : d; + } + + private double cmoveILEforD(int a, int b, double c, double d) { + return (a <= b) ? c : d; + } + + // L for I + private int cmoveLEQforI(long a, long b, int c, int d) { + return (a == b) ? c : d; + } + + private int cmoveLNEforI(long a, long b, int c, int d) { + return (a != b) ? c : d; + } + + private int cmoveLGTforI(long a, long b, int c, int d) { + return (a > b) ? c : d; + } + + private int cmoveLGEforI(long a, long b, int c, int d) { + return (a >= b) ? c : d; + } + + private int cmoveLLTforI(long a, long b, int c, int d) { + return (a < b) ? c : d; + } + + private int cmoveLLEforI(long a, long b, int c, int d) { + return (a <= b) ? c : d; + } + + // L for L + private long cmoveLEQforL(long a, long b, long c, long d) { + return (a == b) ? c : d; + } + + private long cmoveLNEforL(long a, long b, long c, long d) { + return (a != b) ? c : d; + } + + private long cmoveLGTforL(long a, long b, long c, long d) { + return (a > b) ? c : d; + } + + private long cmoveLGEforL(long a, long b, long c, long d) { + return (a >= b) ? c : d; + } + + private long cmoveLLTforL(long a, long b, long c, long d) { + return (a < b) ? c : d; + } + + private long cmoveLLEforL(long a, long b, long c, long d) { + return (a <= b) ? c : d; + } + + // L for F + private float cmoveLEQforF(long a, long b, float c, float d) { + return (a == b) ? c : d; + } + + private float cmoveLNEforF(long a, long b, float c, float d) { + return (a != b) ? c : d; + } + + private float cmoveLGTforF(long a, long b, float c, float d) { + return (a > b) ? c : d; + } + + private float cmoveLGEforF(long a, long b, float c, float d) { + return (a >= b) ? c : d; + } + + private float cmoveLLTforF(long a, long b, float c, float d) { + return (a < b) ? c : d; + } + + private float cmoveLLEforF(long a, long b, float c, float d) { + return (a <= b) ? c : d; + } + + // L for D + private double cmoveLEQforD(long a, long b, double c, double d) { + return (a == b) ? c : d; + } + + private double cmoveLNEforD(long a, long b, double c, double d) { + return (a != b) ? c : d; + } + + private double cmoveLGTforD(long a, long b, double c, double d) { + return (a > b) ? c : d; + } + + private double cmoveLGEforD(long a, long b, double c, double d) { + return (a >= b) ? c : d; + } + + private double cmoveLLTforD(long a, long b, double c, double d) { + return (a < b) ? c : d; + } + + private double cmoveLLEforD(long a, long b, double c, double d) { + return (a <= b) ? c : d; + } + + // Unsigned comparison: I/L + // I for I + private int cmoveUIEQforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) == 0 ? c : d; + } + + private int cmoveUINEforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) != 0 ? c : d; + } + + private int cmoveUIGTforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) > 0 ? c : d; + } + + private int cmoveUIGEforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) >= 0 ? c : d; + } + + private int cmoveUILTforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) < 0 ? c : d; + } + + private int cmoveUILEforI(int a, int b, int c, int d) { + return Integer.compareUnsigned(a, b) <= 0 ? c : d; + } + + // I for L + private long cmoveUIEQforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) == 0 ? c : d; + } + + private long cmoveUINEforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) != 0 ? c : d; + } + + private long cmoveUIGTforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) > 0 ? c : d; + } + + private long cmoveUIGEforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) >= 0 ? c : d; + } + + private long cmoveUILTforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) < 0 ? c : d; + } + + private long cmoveUILEforL(int a, int b, long c, long d) { + return Integer.compareUnsigned(a, b) <= 0 ? c : d; + } + + // I for F + private float cmoveUIEQforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) == 0 ? c : d; + } + + private float cmoveUINEforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) != 0 ? c : d; + } + + private float cmoveUIGTforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) > 0 ? c : d; + } + + private float cmoveUIGEforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) >= 0 ? c : d; + } + + private float cmoveUILTforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) < 0 ? c : d; + } + + private float cmoveUILEforF(int a, int b, float c, float d) { + return Integer.compareUnsigned(a, b) <= 0 ? c : d; + } + + // I for D + private double cmoveUIEQforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) == 0 ? c : d; + } + + private double cmoveUINEforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) != 0 ? c : d; + } + + private double cmoveUIGTforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) > 0 ? c : d; + } + + private double cmoveUIGEforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) >= 0 ? c : d; + } + + private double cmoveUILTforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) < 0 ? c : d; + } + + private double cmoveUILEforD(int a, int b, double c, double d) { + return Integer.compareUnsigned(a, b) <= 0 ? c : d; + } + + // L for I + private int cmoveULEQforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) == 0 ? c : d; + } + + private int cmoveULNEforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) != 0 ? c : d; + } + + private int cmoveULGTforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) > 0 ? c : d; + } + + private int cmoveULGEforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) >= 0 ? c : d; + } + + private int cmoveULLTforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) < 0 ? c : d; + } + + private int cmoveULLEforI(long a, long b, int c, int d) { + return Long.compareUnsigned(a, b) <= 0 ? c : d; + } + + // L for L + private long cmoveULEQforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) == 0 ? c : d; + } + + private long cmoveULNEforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) != 0 ? c : d; + } + + private long cmoveULGTforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) > 0 ? c : d; + } + + private long cmoveULGEforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) >= 0 ? c : d; + } + + private long cmoveULLTforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) < 0 ? c : d; + } + + private long cmoveULLEforL(long a, long b, long c, long d) { + return Long.compareUnsigned(a, b) <= 0 ? c : d; + } + + // L for F + private float cmoveULEQforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) == 0 ? c : d; + } + + private float cmoveULNEforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) != 0 ? c : d; + } + + private float cmoveULGTforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) > 0 ? c : d; + } + + private float cmoveULGEforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) >= 0 ? c : d; + } + + private float cmoveULLTforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) < 0 ? c : d; + } + + private float cmoveULLEforF(long a, long b, float c, float d) { + return Long.compareUnsigned(a, b) <= 0 ? c : d; + } + + // L for D + private double cmoveULEQforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) == 0 ? c : d; + } + + private double cmoveULNEforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) != 0 ? c : d; + } + + private double cmoveULGTforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) > 0 ? c : d; + } + + private double cmoveULGEforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) >= 0 ? c : d; + } + + private double cmoveULLTforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) < 0 ? c : d; + } + + private double cmoveULLEforD(long a, long b, double c, double d) { + return Long.compareUnsigned(a, b) <= 0 ? c : d; + } + + // Float comparison + private int cmoveFGTforI(float a, float b, int c, int d) { + return (a > b) ? c : d; + } + + private long cmoveFGTforL(float a, float b, long c, long d) { + return (a > b) ? c : d; + } + + private float cmoveFGTforF(float a, float b, float c, float d) { + return (a > b) ? c : d; + } + + private double cmoveFGTforD(float a, float b, double c, double d) { + return (a > b) ? c : d; + } + + private int cmoveDGTforI(double a, double b, int c, int d) { + return (a > b) ? c : d; + } + + private long cmoveDGTforL(double a, double b, long c, long d) { + return (a > b) ? c : d; + } + + private float cmoveDGTforF(double a, double b, float c, float d) { + return (a > b) ? c : d; + } + + private double cmoveDGTforD(double a, double b, double c, double d) { + return (a > b) ? c : d; + } + + // Compare 2 values, and pick one of them + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveVFGT(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] > b[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveVFGTSwap(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (b[i] > a[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveVFLT(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] < b[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveVFLTSwap(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (b[i] < a[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveVFEQ(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] == b[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveVDLE(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] <= b[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveVDLESwap(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (b[i] <= a[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveVDGE(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] >= b[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveVDGESwap(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (b[i] >= a[i]) ? a[i] : b[i]; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveVDNE(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] != b[i]) ? a[i] : b[i]; + } + } + + // Extensions: compare 2 values, and pick from 2 consts + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGTforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] > b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGEforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] >= b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFLTforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] < b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFLEforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] <= b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFEQforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] == b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFNEQforFConst(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] != b[i]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f; + c[i+1] = (a[i+1] < b[i+1]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFLEforFConstH2(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f; + c[i+1] = (a[i+1] <= b[i+1]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFYYforFConstH2(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f; + c[i+1] = (a[i+1] < b[i+1]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFXXforFConstH2(float[] a, float[] b, float[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f; + c[i+1] = (a[i+1] <= b[i+1]) ? 0.1f : -0.1f; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDGTforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] > b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDGEforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] >= b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDLTforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] < b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDLEforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] <= b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDEQforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] == b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDNEQforDConst(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i++) { + c[i] = (a[i] != b[i]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDLTforDConstH2(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1; + c[i+1] = (a[i+1] < b[i+1]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDLEforDConstH2(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1; + c[i+1] = (a[i+1] <= b[i+1]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDYYforDConstH2(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1; + c[i+1] = (a[i+1] < b[i+1]) ? 0.1 : -0.1; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDXXforDConstH2(double[] a, double[] b, double[] c) { + for (int i = 0; i < a.length; i+=2) { + c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1; + c[i+1] = (a[i+1] <= b[i+1]) ? 0.1 : -0.1; + } + } + + // Extension: Compare 2 ILFD values, and pick from 2 ILFD values + // Note: + // To guarantee that CMove is introduced, I need to perform the loads before the branch. To ensure they + // do not float down into the branches, I compute a value, and store it to r2 (same as r, except that the + // compilation does not know that). + // So far, CMoveI/L is not guaranteed to be generated, so @IR not verify CMOVE_I/L. + // + // Signed comparison: I/L + // I fo I + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_I, ">0"}) + private static void testCMoveIEQforI(int[] a, int[] 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_I, ">0"}) + private static void testCMoveINEforI(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGTforI(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGEforI(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILTforI(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILEforI(int[] a, int[] 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; + } + } + + // I fo L + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_I, ">0"}) + private static void testCMoveIEQforL(int[] a, int[] 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_I, ">0"}) + private static void testCMoveINEforL(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGTforL(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGEforL(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILTforL(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILEforL(int[] a, int[] 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; + } + } + + // I fo F + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_I, ">0"}) + private static void testCMoveIEQforF(int[] a, int[] 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_I, ">0"}) + private static void testCMoveINEforF(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGTforF(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGEforF(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILTforF(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILEforF(int[] a, int[] 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; + } + } + + // I fo D + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_I, ">0"}) + private static void testCMoveIEQforD(int[] a, int[] 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_I, ">0"}) + private static void testCMoveINEforD(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGTforD(int[] a, int[] 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_I, ">0"}) + private static void testCMoveIGEforD(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILTforD(int[] a, int[] 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_I, ">0"}) + private static void testCMoveILEforD(int[] a, int[] 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; + } + } + + // L fo I + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_I, ">0"}) + private static void testCMoveLEQforI(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLNEforI(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGTforI(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGEforI(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLTforI(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLEforI(long[] a, long[] 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; + } + } + + // L fo L + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_L, ">0"}) + private static void testCMoveLEQforL(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLNEforL(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGTforL(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGEforL(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLTforL(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLEforL(long[] a, long[] 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; + } + } + + // L fo F + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_L, ">0"}) + private static void testCMoveLEQforF(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLNEforF(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGTforF(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGEforF(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLTforF(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLEforF(long[] a, long[] 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; + } + } + + // L fo D + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_L, ">0"}) + private static void testCMoveLEQforD(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLNEforD(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGTforD(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLGEforD(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLTforD(long[] a, long[] 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_L, ">0"}) + private static void testCMoveLLEforD(long[] a, long[] 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; + } + } + + // Unsigned comparison: I/L + // I fo I + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIEQforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUINEforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGTforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGEforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILTforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILEforI(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // I fo L + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIEQforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUINEforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGTforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGEforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILTforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILEforL(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // I fo F + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIEQforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUINEforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGTforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGEforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILTforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILEforF(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // I fo D + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIEQforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUINEforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGTforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUIGEforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILTforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_U, ">0"}) + private static void testCMoveUILEforD(int[] a, int[] 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] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // L fo I + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULEQforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULNEforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGTforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGEforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLTforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLEforI(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // L fo L + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULEQforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULNEforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGTforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGEforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLTforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLEforL(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // L fo F + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULEQforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULNEforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGTforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGEforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLTforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLEforF(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + // L fo D + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULEQforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULNEforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGTforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULGEforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLTforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_UL, ">0"}) + private static void testCMoveULLEforD(long[] a, long[] 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] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // @IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGTforI(float[] a, float[] 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_L, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGTforL(float[] a, float[] 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_F, ">0"}) + private static void testCMoveFGTforF(float[] a, float[] 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_F, ">0"}) + private static void testCMoveFGTforD(float[] a, float[] 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_I, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDGTforI(double[] a, double[] 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_L, ">0", IRNode.CMP_D, ">0"}) + private static void testCMoveDGTforL(double[] a, double[] 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_D, ">0"}) + private static void testCMoveDGTforF(double[] a, double[] 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_D, ">0"}) + private static void testCMoveDGTforD(double[] a, double[] 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; + } + } + + // Use some constants in the comparison + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGTforFCmpCon1(float a, float[] b, float[] c, float[] d, float[] r, float[] r2) { + for (int i = 0; i < b.length; i++) { + float cc = c[i]; + float dd = d[i]; + r2[i] = cc + dd; + r[i] = (a > b[i]) ? cc : dd; + } + } + + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_F, ">0"}) + private static void testCMoveFGTforFCmpCon2(float[] a, float 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) ? cc : dd; + } + } + + // A case that is currently not supported and is not expected to vectorize + @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + private static void testCMoveVDUnsupported() { + double[] doublec = new double[SIZE]; + int seed = 1001; + for (int i = 0; i < doublec.length; i++) { + doublec[i] = (i % 2 == 0) ? seed + i : seed - i; + } + } + + @Warmup(0) + @Run(test = {"testCMoveVFGT", "testCMoveVFLT","testCMoveVDLE", "testCMoveVDGE", "testCMoveVFEQ", "testCMoveVDNE", + "testCMoveVFGTSwap", "testCMoveVFLTSwap","testCMoveVDLESwap", "testCMoveVDGESwap", + "testCMoveFGTforFConst", "testCMoveFGEforFConst", "testCMoveFLTforFConst", + "testCMoveFLEforFConst", "testCMoveFEQforFConst", "testCMoveFNEQforFConst", + "testCMoveDGTforDConst", "testCMoveDGEforDConst", "testCMoveDLTforDConst", + "testCMoveDLEforDConst", "testCMoveDEQforDConst", "testCMoveDNEQforDConst", + "testCMoveFLTforFConstH2", "testCMoveFLEforFConstH2", + "testCMoveFYYforFConstH2", "testCMoveFXXforFConstH2", + "testCMoveDLTforDConstH2", "testCMoveDLEforDConstH2", + "testCMoveDYYforDConstH2", "testCMoveDXXforDConstH2"}) + private void testCMove_runner() { + float[] floata = new float[SIZE]; + float[] floatb = new float[SIZE]; + float[] floatc = new float[SIZE]; + double[] doublea = new double[SIZE]; + double[] doubleb = new double[SIZE]; + double[] doublec = new double[SIZE]; + + init(floata); + init(floatb); + init(doublea); + init(doubleb); + + testCMoveVFGT(floata, floatb, floatc); + testCMoveVDLE(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFloatGT(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDoubleLE(doublea[i], doubleb[i])); + } + + testCMoveVFLT(floata, floatb, floatc); + testCMoveVDGE(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFloatLT(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDoubleGE(doublea[i], doubleb[i])); + } + + // Ensure we frequently have equals + for (int i = 0; i < SIZE; i++) { + if (i % 3 == 0) { + floatb[i] = floata[i]; + doubleb[i] = doublea[i]; + } + } + + testCMoveVFEQ(floata, floatb, floatc); + testCMoveVDNE(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFloatEQ(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDoubleNE(doublea[i], doubleb[i])); + } + + testCMoveVFGTSwap(floata, floatb, floatc); + testCMoveVDLESwap(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFloatGTSwap(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDoubleLESwap(doublea[i], doubleb[i])); + } + + testCMoveVFLTSwap(floata, floatb, floatc); + testCMoveVDGESwap(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFloatLTSwap(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDoubleGESwap(doublea[i], doubleb[i])); + } + + // Extensions: compare 2 values, and pick from 2 consts + testCMoveFGTforFConst(floata, floatb, floatc); + testCMoveDGTforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFGTforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDGTforDConst(doublea[i], doubleb[i])); + } + + testCMoveFGEforFConst(floata, floatb, floatc); + testCMoveDGEforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFGEforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDGEforDConst(doublea[i], doubleb[i])); + } + + testCMoveFLTforFConst(floata, floatb, floatc); + testCMoveDLTforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFLTforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDLTforDConst(doublea[i], doubleb[i])); + } + + testCMoveFLEforFConst(floata, floatb, floatc); + testCMoveDLEforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFLEforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDLEforDConst(doublea[i], doubleb[i])); + } + + testCMoveFEQforFConst(floata, floatb, floatc); + testCMoveDEQforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFEQforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDEQforDConst(doublea[i], doubleb[i])); + } + + testCMoveFNEQforFConst(floata, floatb, floatc); + testCMoveDNEQforDConst(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFNEQforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDNEQforDConst(doublea[i], doubleb[i])); + } + + // Hand-unrolled (H2) examples: + testCMoveFLTforFConstH2(floata, floatb, floatc); + testCMoveDLTforDConstH2(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFLTforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDLTforDConst(doublea[i], doubleb[i])); + } + + testCMoveFLEforFConstH2(floata, floatb, floatc); + testCMoveDLEforDConstH2(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(floatc[i], cmoveFLEforFConst(floata[i], floatb[i])); + Asserts.assertEquals(doublec[i], cmoveDLEforDConst(doublea[i], doubleb[i])); + } + + testCMoveFYYforFConstH2(floata, floatb, floatc); + testCMoveDYYforDConstH2(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i+=2) { + Asserts.assertEquals(floatc[i+0], cmoveFLEforFConst(floata[i+0], floatb[i+0])); + Asserts.assertEquals(doublec[i+0], cmoveDLEforDConst(doublea[i+0], doubleb[i+0])); + Asserts.assertEquals(floatc[i+1], cmoveFLTforFConst(floata[i+1], floatb[i+1])); + Asserts.assertEquals(doublec[i+1], cmoveDLTforDConst(doublea[i+1], doubleb[i+1])); + } + + testCMoveFXXforFConstH2(floata, floatb, floatc); + testCMoveDXXforDConstH2(doublea, doubleb, doublec); + for (int i = 0; i < SIZE; i+=2) { + Asserts.assertEquals(floatc[i+0], cmoveFLTforFConst(floata[i+0], floatb[i+0])); + Asserts.assertEquals(doublec[i+0], cmoveDLTforDConst(doublea[i+0], doubleb[i+0])); + Asserts.assertEquals(floatc[i+1], cmoveFLEforFConst(floata[i+1], floatb[i+1])); + Asserts.assertEquals(doublec[i+1], cmoveDLEforDConst(doublea[i+1], doubleb[i+1])); + } + } + + @Warmup(0) + @Run(test = {// Signed + // I for I + "testCMoveIEQforI", + "testCMoveINEforI", + "testCMoveIGTforI", + "testCMoveIGEforI", + "testCMoveILTforI", + "testCMoveILEforI", + // I for L + "testCMoveIEQforL", + "testCMoveINEforL", + "testCMoveIGTforL", + "testCMoveIGEforL", + "testCMoveILTforL", + "testCMoveILEforL", + // I for F + "testCMoveIEQforF", + "testCMoveINEforF", + "testCMoveIGTforF", + "testCMoveIGEforF", + "testCMoveILTforF", + "testCMoveILEforF", + // I for D + "testCMoveIEQforD", + "testCMoveINEforD", + "testCMoveIGTforD", + "testCMoveIGEforD", + "testCMoveILTforD", + "testCMoveILEforD", + // L for I + "testCMoveLEQforI", + "testCMoveLNEforI", + "testCMoveLGTforI", + "testCMoveLGEforI", + "testCMoveLLTforI", + "testCMoveLLEforI", + // L for L + "testCMoveLEQforL", + "testCMoveLNEforL", + "testCMoveLGTforL", + "testCMoveLGEforL", + "testCMoveLLTforL", + "testCMoveLLEforL", + // L for F + "testCMoveLEQforF", + "testCMoveLNEforF", + "testCMoveLGTforF", + "testCMoveLGEforF", + "testCMoveLLTforF", + "testCMoveLLEforF", + // L for D + "testCMoveLEQforD", + "testCMoveLNEforD", + "testCMoveLGTforD", + "testCMoveLGEforD", + "testCMoveLLTforD", + "testCMoveLLEforD", + // Unsigned + // I for I + "testCMoveUIEQforI", + "testCMoveUINEforI", + "testCMoveUIGTforI", + "testCMoveUIGEforI", + "testCMoveUILTforI", + "testCMoveUILEforI", + // I for L + "testCMoveUIEQforL", + "testCMoveUINEforL", + "testCMoveUIGTforL", + "testCMoveUIGEforL", + "testCMoveUILTforL", + "testCMoveUILEforL", + // I for F + "testCMoveUIEQforF", + "testCMoveUINEforF", + "testCMoveUIGTforF", + "testCMoveUIGEforF", + "testCMoveUILTforF", + "testCMoveUILEforF", + // I for D + "testCMoveUIEQforD", + "testCMoveUINEforD", + "testCMoveUIGTforD", + "testCMoveUIGEforD", + "testCMoveUILTforD", + "testCMoveUILEforD", + // L for I + "testCMoveULEQforI", + "testCMoveULNEforI", + "testCMoveULGTforI", + "testCMoveULGEforI", + "testCMoveULLTforI", + "testCMoveULLEforI", + // L for L + "testCMoveULEQforL", + "testCMoveULNEforL", + "testCMoveULGTforL", + "testCMoveULGEforL", + "testCMoveULLTforL", + "testCMoveULLEforL", + // L for F + "testCMoveULEQforF", + "testCMoveULNEforF", + "testCMoveULGTforF", + "testCMoveULGEforF", + "testCMoveULLTforF", + "testCMoveULLEforF", + // L for D + "testCMoveULEQforD", + "testCMoveULNEforD", + "testCMoveULGTforD", + "testCMoveULGEforD", + "testCMoveULLTforD", + "testCMoveULLEforD", + // Float + "testCMoveFGTforI", + "testCMoveFGTforL", + "testCMoveFGTforF", + "testCMoveFGTforD", + "testCMoveDGTforI", + "testCMoveDGTforL", + "testCMoveDGTforF", + "testCMoveDGTforD", + "testCMoveFGTforFCmpCon1", + "testCMoveFGTforFCmpCon2"}) + private void testCMove_runner_two() { + int[] aI = new int[SIZE]; + int[] bI = new int[SIZE]; + int[] cI = new int[SIZE]; + int[] dI = new int[SIZE]; + int[] rI = new int[SIZE]; + long[] aL = new long[SIZE]; + long[] bL = new long[SIZE]; + long[] cL = new long[SIZE]; + long[] dL = new long[SIZE]; + long[] rL = new long[SIZE]; + float[] aF = new float[SIZE]; + float[] bF = new float[SIZE]; + float[] cF = new float[SIZE]; + float[] dF = new float[SIZE]; + float[] rF = new float[SIZE]; + double[] aD = new double[SIZE]; + double[] bD = new double[SIZE]; + double[] cD = new double[SIZE]; + double[] dD = new double[SIZE]; + double[] rD = new double[SIZE]; + + init(aI); + init(bI); + init(cI); + init(dI); + init(aL); + init(bL); + init(cL); + init(dL); + init(aF); + init(bF); + init(cF); + init(dF); + init(aD); + init(bD); + init(cD); + init(dD); + + // Signed + // I for I + testCMoveIEQforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveIEQforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveINEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveINEforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveIGTforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveIGTforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveIGEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveIGEforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveILTforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveILTforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveILEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveILEforI(aI[i], bI[i], cI[i], dI[i])); + } + + // I for L + testCMoveIEQforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveIEQforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveINEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveINEforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveIGTforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveIGTforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveIGEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveIGEforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveILTforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveILTforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveILEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveILEforL(aI[i], bI[i], cL[i], dL[i])); + } + + // I for F + testCMoveIEQforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveIEQforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveINEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveINEforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveIGTforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveIGTforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveIGEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveIGEforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveILTforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveILTforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveILEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveILEforF(aI[i], bI[i], cF[i], dF[i])); + } + + // I for D + boolean passed = true; + testCMoveIEQforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveIEQforD(aI[i], bI[i], cD[i], dD[i])); + } + Asserts.assertEquals(passed, true); + + testCMoveINEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveINEforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveIGTforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveIGTforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveIGEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveIGEforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveILTforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveILTforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveILEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveILEforD(aI[i], bI[i], cD[i], dD[i])); + } + + // L for I + testCMoveLEQforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLEQforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveLNEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLNEforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveLGTforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLGTforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveLGEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLGEforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveLLTforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLLTforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveLLEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveLLEforI(aL[i], bL[i], cI[i], dI[i])); + } + + // L for L + testCMoveLEQforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLEQforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveLNEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLNEforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveLGTforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLGTforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveLGEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLGEforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveLLTforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLLTforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveLLEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveLLEforL(aL[i], bL[i], cL[i], dL[i])); + } + + // L for F + testCMoveLEQforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLEQforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveLNEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLNEforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveLGTforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLGTforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveLGEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLGEforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveLLTforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLLTforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveLLEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveLLEforF(aL[i], bL[i], cF[i], dF[i])); + } + + // L for D + testCMoveLEQforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLEQforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveLNEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLNEforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveLGTforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLGTforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveLGEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLGEforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveLLTforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLLTforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveLLEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveLLEforD(aL[i], bL[i], cD[i], dD[i])); + } + + // Unsigned + // I for I + testCMoveUIEQforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUIEQforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveUINEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUINEforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveUIGTforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUIGTforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveUIGEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUIGEforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveUILTforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUILTforI(aI[i], bI[i], cI[i], dI[i])); + } + + testCMoveUILEforI(aI, bI, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveUILEforI(aI[i], bI[i], cI[i], dI[i])); + } + + // I for L + testCMoveUIEQforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUIEQforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveUINEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUINEforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveUIGTforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUIGTforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveUIGEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUIGEforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveUILTforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUILTforL(aI[i], bI[i], cL[i], dL[i])); + } + + testCMoveUILEforL(aI, bI, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveUILEforL(aI[i], bI[i], cL[i], dL[i])); + } + + // I for F + testCMoveUIEQforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUIEQforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveUINEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUINEforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveUIGTforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUIGTforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveUIGEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUIGEforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveUILTforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUILTforF(aI[i], bI[i], cF[i], dF[i])); + } + + testCMoveUILEforF(aI, bI, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveUILEforF(aI[i], bI[i], cF[i], dF[i])); + } + + // I for D + testCMoveUIEQforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUIEQforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveUINEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUINEforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveUIGTforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUIGTforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveUIGEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUIGEforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveUILTforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUILTforD(aI[i], bI[i], cD[i], dD[i])); + } + + testCMoveUILEforD(aI, bI, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveUILEforD(aI[i], bI[i], cD[i], dD[i])); + } + + // L for I + testCMoveULEQforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULEQforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveULNEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULNEforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveULGTforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULGTforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveULGEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULGEforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveULLTforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULLTforI(aL[i], bL[i], cI[i], dI[i])); + } + + testCMoveULLEforI(aL, bL, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveULLEforI(aL[i], bL[i], cI[i], dI[i])); + } + + // L for L + testCMoveULEQforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULEQforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveULNEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULNEforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveULGTforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULGTforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveULGEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULGEforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveULLTforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULLTforL(aL[i], bL[i], cL[i], dL[i])); + } + + testCMoveULLEforL(aL, bL, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveULLEforL(aL[i], bL[i], cL[i], dL[i])); + } + + // L for F + testCMoveULEQforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULEQforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveULNEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULNEforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveULGTforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULGTforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveULGEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULGEforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveULLTforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULLTforF(aL[i], bL[i], cF[i], dF[i])); + } + + testCMoveULLEforF(aL, bL, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveULLEforF(aL[i], bL[i], cF[i], dF[i])); + } + + // L for D + testCMoveULEQforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULEQforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveULNEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULNEforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveULGTforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULGTforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveULGEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULGEforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveULLTforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULLTforD(aL[i], bL[i], cD[i], dD[i])); + } + + testCMoveULLEforD(aL, bL, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveULLEforD(aL[i], bL[i], cD[i], dD[i])); + } + + // Float + testCMoveFGTforI(aF, bF, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveFGTforI(aF[i], bF[i], cI[i], dI[i])); + } + + testCMoveFGTforL(aF, bF, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveFGTforL(aF[i], bF[i], cL[i], dL[i])); + } + + testCMoveFGTforF(aF, bF, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveFGTforF(aF[i], bF[i], cF[i], dF[i])); + } + + testCMoveFGTforD(aF, bF, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveFGTforD(aF[i], bF[i], cD[i], dD[i])); + } + + testCMoveDGTforI(aD, bD, cI, dI, rI, rI); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rI[i], cmoveDGTforI(aD[i], bD[i], cI[i], dI[i])); + } + + testCMoveDGTforL(aD, bD, cL, dL, rL, rL); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rL[i], cmoveDGTforL(aD[i], bD[i], cL[i], dL[i])); + } + + testCMoveDGTforF(aD, bD, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveDGTforF(aD[i], bD[i], cF[i], dF[i])); + } + + testCMoveDGTforD(aD, bD, cD, dD, rD, rD); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rD[i], cmoveDGTforD(aD[i], bD[i], cD[i], dD[i])); + } + + // Use some constants/invariants in the comparison + testCMoveFGTforFCmpCon1(aF[0], bF, cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveFGTforF(aF[0], bF[i], cF[i], dF[i])); + } + + testCMoveFGTforFCmpCon2(aF, bF[0], cF, dF, rF, rF); + for (int i = 0; i < SIZE; i++) { + Asserts.assertEquals(rF[i], cmoveFGTforF(aF[i], bF[0], cF[i], dF[i])); + } + } + + 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()); + }; + } + } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java index 4759add94e9cf..bf08688cf4219 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java @@ -1,6 +1,7 @@ /* - * Copyright (c) 2022, Arm Limited. All rights reserved. - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Arm Limited. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -586,7 +587,7 @@ private double cmoveDGTforD(double a, double b, double c, double d) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVFGT(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] > b[i]) ? a[i] : b[i]; @@ -598,7 +599,7 @@ private static void testCMoveVFGT(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVFGTSwap(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (b[i] > a[i]) ? a[i] : b[i]; @@ -610,7 +611,7 @@ private static void testCMoveVFGTSwap(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVFLT(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] < b[i]) ? a[i] : b[i]; @@ -622,7 +623,7 @@ private static void testCMoveVFLT(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVFLTSwap(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (b[i] < a[i]) ? a[i] : b[i]; @@ -634,7 +635,7 @@ private static void testCMoveVFLTSwap(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVFEQ(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] == b[i]) ? a[i] : b[i]; @@ -646,7 +647,7 @@ private static void testCMoveVFEQ(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVDLE(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] <= b[i]) ? a[i] : b[i]; @@ -658,7 +659,7 @@ private static void testCMoveVDLE(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVDLESwap(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (b[i] <= a[i]) ? a[i] : b[i]; @@ -670,7 +671,7 @@ private static void testCMoveVDLESwap(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVDGE(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] >= b[i]) ? a[i] : b[i]; @@ -682,7 +683,7 @@ private static void testCMoveVDGE(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVDGESwap(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (b[i] >= a[i]) ? a[i] : b[i]; @@ -694,7 +695,7 @@ private static void testCMoveVDGESwap(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveVDNE(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] != b[i]) ? a[i] : b[i]; @@ -707,7 +708,7 @@ private static void testCMoveVDNE(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFGTforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] > b[i]) ? 0.1f : -0.1f; @@ -719,7 +720,7 @@ private static void testCMoveFGTforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFGEforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] >= b[i]) ? 0.1f : -0.1f; @@ -731,7 +732,7 @@ private static void testCMoveFGEforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFLTforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] < b[i]) ? 0.1f : -0.1f; @@ -743,7 +744,7 @@ private static void testCMoveFLTforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFLEforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] <= b[i]) ? 0.1f : -0.1f; @@ -755,7 +756,7 @@ private static void testCMoveFLEforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFEQforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] == b[i]) ? 0.1f : -0.1f; @@ -767,7 +768,7 @@ private static void testCMoveFEQforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFNEQforFConst(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] != b[i]) ? 0.1f : -0.1f; @@ -780,7 +781,7 @@ private static void testCMoveFNEQforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f; @@ -798,7 +799,7 @@ private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) { IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFLEforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f; @@ -815,7 +816,7 @@ private static void testCMoveFLEforFConstH2(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, "=0", IRNode.VECTOR_BLEND_F, "=0", IRNode.STORE_VECTOR, "=0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFYYforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f; @@ -828,7 +829,7 @@ private static void testCMoveFYYforFConstH2(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, "=0", IRNode.VECTOR_BLEND_F, "=0", IRNode.STORE_VECTOR, "=0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFXXforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f; @@ -841,7 +842,7 @@ private static void testCMoveFXXforFConstH2(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDGTforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] > b[i]) ? 0.1 : -0.1; @@ -853,7 +854,7 @@ private static void testCMoveDGTforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDGEforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] >= b[i]) ? 0.1 : -0.1; @@ -865,7 +866,7 @@ private static void testCMoveDGEforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDLTforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] < b[i]) ? 0.1 : -0.1; @@ -877,7 +878,7 @@ private static void testCMoveDLTforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDLEforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] <= b[i]) ? 0.1 : -0.1; @@ -889,7 +890,7 @@ private static void testCMoveDLEforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDEQforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] == b[i]) ? 0.1 : -0.1; @@ -901,7 +902,7 @@ private static void testCMoveDEQforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDNEQforDConst(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i++) { c[i] = (a[i] != b[i]) ? 0.1 : -0.1; @@ -913,7 +914,7 @@ private static void testCMoveDNEQforDConst(double[] a, double[] b, double[] c) { IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDLTforDConstH2(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1; @@ -926,7 +927,7 @@ private static void testCMoveDLTforDConstH2(double[] a, double[] b, double[] c) IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDLEforDConstH2(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1; @@ -939,7 +940,7 @@ private static void testCMoveDLEforDConstH2(double[] a, double[] b, double[] c) IRNode.VECTOR_MASK_CMP_D, "=0", IRNode.VECTOR_BLEND_D, "=0", IRNode.STORE_VECTOR, "=0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDYYforDConstH2(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1; @@ -952,7 +953,7 @@ private static void testCMoveDYYforDConstH2(double[] a, double[] b, double[] c) IRNode.VECTOR_MASK_CMP_D, "=0", IRNode.VECTOR_BLEND_D, "=0", IRNode.STORE_VECTOR, "=0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDXXforDConstH2(double[] a, double[] b, double[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1; @@ -966,6 +967,7 @@ private static void testCMoveDXXforDConstH2(double[] a, double[] b, double[] c) // do not float down into the branches, I compute a value, and store it to r2 (same as r, except that the // compilation does not know that). // So far, vectorization only works for CMoveF/D, with same data-width comparison (F/I for F, D/L for D). + // // Signed comparison: I/L // I fo I @Test @@ -1108,7 +1110,7 @@ private static void testCMoveILEforL(int[] a, int[] b, long[] c, long[] d, long[ IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveIEQforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1124,7 +1126,7 @@ private static void testCMoveIEQforF(int[] a, int[] b, float[] c, float[] d, flo IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveINEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1140,7 +1142,7 @@ private static void testCMoveINEforF(int[] a, int[] b, float[] c, float[] d, flo IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveIGTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1156,7 +1158,7 @@ private static void testCMoveIGTforF(int[] a, int[] b, float[] c, float[] d, flo IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveIGEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1172,7 +1174,7 @@ private static void testCMoveIGEforF(int[] a, int[] b, float[] c, float[] d, flo IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveILTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1188,7 +1190,7 @@ private static void testCMoveILTforF(int[] a, int[] b, float[] c, float[] d, flo IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveILEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1200,7 +1202,13 @@ private static void testCMoveILEforF(int[] a, int[] b, float[] c, float[] d, flo // I fo D @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveIEQforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1211,7 +1219,13 @@ private static void testCMoveIEQforD(int[] a, int[] b, double[] c, double[] d, d } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveINEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1222,7 +1236,13 @@ private static void testCMoveINEforD(int[] a, int[] b, double[] c, double[] d, d } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveIGTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1233,7 +1253,13 @@ private static void testCMoveIGTforD(int[] a, int[] b, double[] c, double[] d, d } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveIGEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1244,7 +1270,13 @@ private static void testCMoveIGEforD(int[] a, int[] b, double[] c, double[] d, d } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveILTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1255,7 +1287,13 @@ private static void testCMoveILTforD(int[] a, int[] b, double[] c, double[] d, d } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveILEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1401,7 +1439,13 @@ private static void testCMoveLLEforL(long[] a, long[] b, long[] c, long[] d, lon // L fo F @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLEQforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1412,7 +1456,13 @@ private static void testCMoveLEQforF(long[] a, long[] b, float[] c, float[] d, f } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLNEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1423,7 +1473,13 @@ private static void testCMoveLNEforF(long[] a, long[] b, float[] c, float[] d, f } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLGTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1434,7 +1490,13 @@ private static void testCMoveLGTforF(long[] a, long[] b, float[] c, float[] d, f } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLGEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1445,7 +1507,13 @@ private static void testCMoveLGEforF(long[] a, long[] b, float[] c, float[] d, f } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLLTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1456,7 +1524,13 @@ private static void testCMoveLLTforF(long[] a, long[] b, float[] c, float[] d, f } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveLLEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1473,7 +1547,7 @@ private static void testCMoveLLEforF(long[] a, long[] b, float[] c, float[] d, f IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLEQforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1490,7 +1564,7 @@ private static void testCMoveLEQforD(long[] a, long[] b, double[] c, double[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLNEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1507,7 +1581,7 @@ private static void testCMoveLNEforD(long[] a, long[] b, double[] c, double[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLGTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1524,7 +1598,7 @@ private static void testCMoveLGTforD(long[] a, long[] b, double[] c, double[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLGEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1541,7 +1615,7 @@ private static void testCMoveLGEforD(long[] a, long[] b, double[] c, double[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLLTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1558,7 +1632,7 @@ private static void testCMoveLLTforD(long[] a, long[] b, double[] c, double[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveLLEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -1711,7 +1785,7 @@ private static void testCMoveUILEforL(int[] a, int[] b, long[] c, long[] d, long IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUIEQforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1727,7 +1801,7 @@ private static void testCMoveUIEQforF(int[] a, int[] b, float[] c, float[] d, fl IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUINEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1743,7 +1817,7 @@ private static void testCMoveUINEforF(int[] a, int[] b, float[] c, float[] d, fl IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUIGTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1759,7 +1833,7 @@ private static void testCMoveUIGTforF(int[] a, int[] b, float[] c, float[] d, fl IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUIGEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1775,7 +1849,7 @@ private static void testCMoveUIGEforF(int[] a, int[] b, float[] c, float[] d, fl IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUILTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1791,7 +1865,7 @@ private static void testCMoveUILTforF(int[] a, int[] b, float[] c, float[] d, fl IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveUILEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -1803,7 +1877,13 @@ private static void testCMoveUILEforF(int[] a, int[] b, float[] c, float[] d, fl // I fo D @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUIEQforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1814,7 +1894,13 @@ private static void testCMoveUIEQforD(int[] a, int[] b, double[] c, double[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUINEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1825,7 +1911,13 @@ private static void testCMoveUINEforD(int[] a, int[] b, double[] c, double[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUIGTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1836,7 +1928,13 @@ private static void testCMoveUIGTforD(int[] a, int[] b, double[] c, double[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUIGEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1847,7 +1945,13 @@ private static void testCMoveUIGEforD(int[] a, int[] b, double[] c, double[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUILTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -1858,7 +1962,13 @@ private static void testCMoveUILTforD(int[] a, int[] b, double[] c, double[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_int, max_double)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveUILEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -2004,7 +2114,13 @@ private static void testCMoveULLEforL(long[] a, long[] b, long[] c, long[] d, lo // L fo F @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULEQforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2015,7 +2131,13 @@ private static void testCMoveULEQforF(long[] a, long[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULNEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2026,7 +2148,13 @@ private static void testCMoveULNEforF(long[] a, long[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULGTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2037,7 +2165,13 @@ private static void testCMoveULGTforF(long[] a, long[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULGEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2048,7 +2182,13 @@ private static void testCMoveULGEforF(long[] a, long[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULLTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2059,7 +2199,13 @@ private static void testCMoveULLTforF(long[] a, long[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_long, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveULLEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2076,7 +2222,7 @@ private static void testCMoveULLEforF(long[] a, long[] b, float[] c, float[] d, IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULEQforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2093,7 +2239,7 @@ private static void testCMoveULEQforD(long[] a, long[] b, double[] c, double[] d IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULNEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2110,7 +2256,7 @@ private static void testCMoveULNEforD(long[] a, long[] b, double[] c, double[] d IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULGTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2127,7 +2273,7 @@ private static void testCMoveULGTforD(long[] a, long[] b, double[] c, double[] d IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULGEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2144,7 +2290,7 @@ private static void testCMoveULGEforD(long[] a, long[] b, double[] c, double[] d IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULLTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2161,7 +2307,7 @@ private static void testCMoveULLTforD(long[] a, long[] b, double[] c, double[] d IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true", "rvv", "true"}) // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4. private static void testCMoveULLEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { @@ -2199,7 +2345,7 @@ private static void testCMoveFGTforL(float[] a, float[] b, long[] c, long[] d, l IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFGTforF(float[] a, float[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2210,7 +2356,13 @@ private static void testCMoveFGTforF(float[] a, float[] b, float[] c, float[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_double, max_float)", ">0", + IRNode.LOAD_VECTOR_D, ">0", + IRNode.VECTOR_MASK_CMP_F, IRNode.VECTOR_SIZE + "min(max_double, max_float)", ">0", + IRNode.VECTOR_BLEND_D, ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveFGTforD(float[] a, float[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -2243,7 +2395,13 @@ private static void testCMoveDGTforL(double[] a, double[] b, long[] c, long[] d, } @Test - @IR(failOn = {IRNode.STORE_VECTOR}) + @IR(counts = {IRNode.LOAD_VECTOR_D, ">0", + IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_double, max_float)", ">0", + IRNode.VECTOR_MASK_CMP_D, ">0", + IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_double, max_float)", ">0", + IRNode.STORE_VECTOR, ">0"}, + applyIfCPUFeatureOr = {"rvv", "true"}) + @IR(failOn = {IRNode.STORE_VECTOR}, applyIfCPUFeatureOr = {"rvv", "false"}) private static void testCMoveDGTforF(double[] a, double[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2258,7 +2416,7 @@ private static void testCMoveDGTforF(double[] a, double[] b, float[] c, float[] IRNode.VECTOR_MASK_CMP_D, ">0", IRNode.VECTOR_BLEND_D, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveDGTforD(double[] a, double[] b, double[] c, double[] d, double[] r, double[] r2) { for (int i = 0; i < a.length; i++) { double cc = c[i]; @@ -2274,7 +2432,7 @@ private static void testCMoveDGTforD(double[] a, double[] b, double[] c, double[ IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFGTforFCmpCon1(float a, float[] b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < b.length; i++) { float cc = c[i]; @@ -2289,7 +2447,7 @@ private static void testCMoveFGTforFCmpCon1(float a, float[] b, float[] c, float IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, - applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) + applyIfCPUFeatureOr = {"avx", "true", "asimd", "true", "rvv", "true"}) private static void testCMoveFGTforFCmpCon2(float[] a, float b, float[] c, float[] d, float[] r, float[] r2) { for (int i = 0; i < a.length; i++) { float cc = c[i]; @@ -2714,10 +2872,12 @@ private void testCMove_runner_two() { } // I for D + boolean passed = true; testCMoveIEQforD(aI, bI, cD, dD, rD, rD); for (int i = 0; i < SIZE; i++) { Asserts.assertEquals(rD[i], cmoveIEQforD(aI[i], bI[i], cD[i], dD[i])); } + Asserts.assertEquals(passed, true); testCMoveINEforD(aI, bI, cD, dD, rD, rD); for (int i = 0; i < SIZE; i++) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 80429ad868aaf..5bfc6495db8ae 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -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"); diff --git a/test/micro/org/openjdk/bench/java/lang/ClassComparison.java b/test/micro/org/openjdk/bench/java/lang/ClassComparison.java index 2a768f243e2bf..15e631bb7fce5 100644 --- a/test/micro/org/openjdk/bench/java/lang/ClassComparison.java +++ b/test/micro/org/openjdk/bench/java/lang/ClassComparison.java @@ -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 void setup() { 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 void notEqualClass() { } } + @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 void notEqualClassResLong() { 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; + } + } } diff --git a/test/micro/org/openjdk/bench/java/lang/FPComparison.java b/test/micro/org/openjdk/bench/java/lang/FPComparison.java index 8074ada325797..18b2b79c7bde4 100644 --- a/test/micro/org/openjdk/bench/java/lang/FPComparison.java +++ b/test/micro/org/openjdk/bench/java/lang/FPComparison.java @@ -37,34 +37,18 @@ 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 void greaterEqualDoubleResLong() { 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; + } + } } diff --git a/test/micro/org/openjdk/bench/java/lang/IntegerComparison.java b/test/micro/org/openjdk/bench/java/lang/IntegerComparison.java index 1853be8497d87..832d398fc3d27 100644 --- a/test/micro/org/openjdk/bench/java/lang/IntegerComparison.java +++ b/test/micro/org/openjdk/bench/java/lang/IntegerComparison.java @@ -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 void setup() { 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 void greaterEqualInteger() { } } + // 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 void notEqualIntegerResLong() { } } + @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 void lessEqualIntegerResLong() { } } + @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 void greaterEqualIntegerResLong() { 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; + } + } } diff --git a/test/micro/org/openjdk/bench/java/lang/LongComparison.java b/test/micro/org/openjdk/bench/java/lang/LongComparison.java index bed5ee245b2a7..a7317244c6f61 100644 --- a/test/micro/org/openjdk/bench/java/lang/LongComparison.java +++ b/test/micro/org/openjdk/bench/java/lang/LongComparison.java @@ -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 void setup() { 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 void greaterEqualLong() { } } + // 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 void notEqualLongResLong() { } } + @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 void lessEqualLongResLong() { } } + @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 void greaterEqualLongResLong() { 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; + } + } } diff --git a/test/micro/org/openjdk/bench/java/lang/PointerComparison.java b/test/micro/org/openjdk/bench/java/lang/PointerComparison.java index b6bcf00861923..fc2fd95b1c00e 100644 --- a/test/micro/org/openjdk/bench/java/lang/PointerComparison.java +++ b/test/micro/org/openjdk/bench/java/lang/PointerComparison.java @@ -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 void setup() { 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 void notEqualObject() { } } + @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 void notEqualObjectResLong() { 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; + } + } }