diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 77b4e26cc924b..ce13ebde74f9b 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2170,15 +2170,13 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe cmov_cmp_fp_le(op1, op2, dst, src, is_single); break; case BoolTest::ge: - assert(false, "Should go to BoolTest::le case"); - ShouldNotReachHere(); + cmov_cmp_fp_ge(op1, op2, dst, src, is_single); break; case BoolTest::lt: cmov_cmp_fp_lt(op1, op2, dst, src, is_single); break; case BoolTest::gt: - assert(false, "Should go to BoolTest::lt case"); - ShouldNotReachHere(); + cmov_cmp_fp_gt(op1, op2, dst, src, is_single); break; default: assert(false, "unsupported compare condition"); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index bc6bf88d0ad6a..12c702b6d1324 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1268,12 +1268,19 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist } // ----------- cmove, compare float ----------- +// +// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple, +// so, just list behaviour of unordered ones as follow. +// +// Set dst (CMoveI (Binary cop (CmpF/D op1 op2)) (Binary dst src)) +// (If one or both inputs to the compare are NaN, then) +// 1. (op1 lt op2) => true => CMove: dst = src +// 2. (op1 le op2) => true => CMove: dst = src +// 3. (op1 gt op2) => false => CMove: dst = dst +// 4. (op1 ge op2) => false => CMove: dst = dst +// 5. (op1 eq op2) => false => CMove: dst = dst +// 6. (op1 ne op2) => true => CMove: dst = src -// 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_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { @@ -1289,7 +1296,7 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 != cmp2, including the case of NaN - // not jump (i.e. move src to dst) if cmp1 == cmp2 + // fallthrough (i.e. move src to dst) if cmp1 == cmp2 float_bne(cmp1, cmp2, no_set); } else { double_bne(cmp1, cmp2, no_set); @@ -1298,11 +1305,6 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi 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_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { @@ -1318,7 +1320,7 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 == cmp2 - // not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN + // fallthrough (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); @@ -1327,14 +1329,6 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi 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_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { @@ -1350,7 +1344,7 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 > cmp2 - // not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN + // fallthrough (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); @@ -1359,14 +1353,30 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi 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_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { + if (UseZicond) { + if (is_single) { + fle_s(t0, cmp2, cmp1); + } else { + fle_d(t0, cmp2, cmp1); + } + czero_nez(dst, dst, t0); + czero_eqz(t0 , src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + if (is_single) { + // jump if cmp1 < cmp2 or either is NaN + // fallthrough (i.e. move src to dst) if cmp1 >= cmp2 + float_blt(cmp1, cmp2, no_set, false, true); + } else { + double_blt(cmp1, cmp2, no_set, false, true); + } + mv(dst, src); + bind(no_set); +} + void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { @@ -1382,7 +1392,7 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 >= cmp2 - // not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN + // fallthrough (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); @@ -1391,6 +1401,30 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi bind(no_set); } +void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { + if (UseZicond) { + if (is_single) { + flt_s(t0, cmp2, cmp1); + } else { + flt_d(t0, cmp2, cmp1); + } + czero_nez(dst, dst, t0); + czero_eqz(t0 , src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + if (is_single) { + // jump if cmp1 <= cmp2 or either is NaN + // fallthrough (i.e. move src to dst) if cmp1 > cmp2 + float_ble(cmp1, cmp2, no_set, false, true); + } else { + double_ble(cmp1, cmp2, no_set, false, true); + } + mv(dst, src); + bind(no_set); +} + // Float compare branch instructions #define INSN(NAME, FLOATCMP, BRANCH) \ diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 6f80a02ddc6a1..89ead519d263f 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -660,7 +660,9 @@ class MacroAssembler: public Assembler { void cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single); void cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single); void cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single); + void cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single); 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); public: // We try to follow risc-v asm menomics. diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java new file mode 100644 index 0000000000000..59c70b6873fb4 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -0,0 +1,1005 @@ +/* + * 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.List; + +/* + * @test + * @bug 8358892 + * @summary The test is to trigger code path of BoolTest::ge/gt in C2_MacroAssembler::enc_cmove_cmp_fp + * @requires os.arch == "riscv64" + * @requires vm.debug + * @library /test/lib / + * @run driver compiler.c2.irTests.TestFPComparison2 + */ +public class TestFPComparison2 { + static final double[] DOUBLES = new double[] { + Double.NEGATIVE_INFINITY, + -Double.MAX_VALUE, + -1.0, + -Double.MIN_VALUE, + -0.0, + 0.0, + Double.MIN_VALUE, + 1.0, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + Double.NaN, + }; + + static final float[] FLOATS = new float[] { + Float.NEGATIVE_INFINITY, + -Float.MAX_VALUE, + -1.0F, + -Float.MIN_VALUE, + -0.0F, + 0.0F, + Float.MIN_VALUE, + 1.0F, + Float.MAX_VALUE, + Float.POSITIVE_INFINITY, + Float.NaN, + }; + + static final int[] INTS = new int[] { + Integer.MIN_VALUE, + -100, + -1, + 0, + 1, + 100, + Integer.MAX_VALUE, + }; + + public static void main(String[] args) { + List options = List.of("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace"); + // Booltest::ge + TestFramework framework = new TestFramework(Test_ge_1.class); + framework.addFlags(options.toArray(new String[0])).start(); + + framework = new TestFramework(Test_ge_2.class); + framework.addFlags(options.toArray(new String[0])).start(); + + // Booltest::gt + framework = new TestFramework(Test_gt_1.class); + framework.addFlags(options.toArray(new String[0])).start(); + + framework = new TestFramework(Test_gt_2.class); + framework.addFlags(options.toArray(new String[0])).start(); + } +} + +class Test_ge_1 { + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_1_0(float x, float y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x > y + // return 0 + // when neither is NaN, and x <= y + return !(x <= y) ? 1 : 0; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_1_0(float x, float y) { + return !(x <= y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_1_0(double x, double y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x > y + // return 0 + // when neither is NaN, and x <= y + return !(x <= y) ? 1 : 0; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_1_0(double x, double y) { + return !(x <= y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_0_1(float x, float y) { + return !(x <= y) ? 0 : 1; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_0_1(float x, float y) { + return !(x <= y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_0_1(double x, double y) { + return !(x <= y) ? 0 : 1; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_0_1(double x, double y) { + return !(x <= y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_10_20(float x, float y) { + return !(x <= y) ? 10 : 20; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_10_20(float x, float y) { + return !(x <= y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_10_20(double x, double y) { + return !(x <= y) ? 10 : 20; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_10_20(double x, double y) { + return !(x <= y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_variable_results(float x, float y, int a, int b) { + return !(x <= y) ? a : b; + } + @DontCompile + public static int golden_float_BoolTest_ge_variable_results(float x, float y, int a, int b) { + return !(x <= y) ? a : b; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_variable_results(double x, double y, int a, int b) { + return !(x <= y) ? a : b; + } + @DontCompile + public static int golden_double_BoolTest_ge_variable_results(double x, double y, int a, int b) { + return !(x <= y) ? a : b; + } + + @Run(test = {"test_float_BoolTest_ge_fixed_1_0", "test_double_BoolTest_ge_fixed_1_0", + "test_float_BoolTest_ge_fixed_0_1", "test_double_BoolTest_ge_fixed_0_1", + "test_float_BoolTest_ge_fixed_10_20", "test_double_BoolTest_ge_fixed_10_20", + "test_float_BoolTest_ge_variable_results", "test_double_BoolTest_ge_variable_results"}) + public void runTests() { + int err = 0; + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_1_0(x, y); + int expected = golden_float_BoolTest_ge_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Float failed (ge, 1, 0), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_1_0(x, y); + int expected = golden_double_BoolTest_ge_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Double failed (ge, 1, 0), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_0_1(x, y); + int expected = golden_float_BoolTest_ge_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Float failed (ge, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_0_1(x, y); + int expected = golden_double_BoolTest_ge_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Double failed (ge, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_10_20(x, y); + int expected = golden_float_BoolTest_ge_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Float failed (ge, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_10_20(x, y); + int expected = golden_double_BoolTest_ge_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Double failed (ge, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_float_BoolTest_ge_variable_results(x, y, a, b); + int expected = golden_float_BoolTest_ge_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Float failed (ge), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_double_BoolTest_ge_variable_results(x, y, a, b); + int expected = golden_double_BoolTest_ge_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Double failed (ge), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + if (err != 0) { + throw new RuntimeException("Some tests failed"); + } + } +} + +class Test_ge_2 { + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_1_0(float x, float y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x < y + // return 0 + // when neither is NaN, and x >= y + return !(x >= y) ? 1 : 0; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_1_0(float x, float y) { + return !(x >= y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_1_0(double x, double y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x < y + // return 0 + // when neither is NaN, and x >= y + return !(x >= y) ? 1 : 0; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_1_0(double x, double y) { + return !(x >= y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_0_1(float x, float y) { + return !(x >= y) ? 0 : 1; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_0_1(float x, float y) { + return !(x >= y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_0_1(double x, double y) { + return !(x >= y) ? 0 : 1; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_0_1(double x, double y) { + return !(x >= y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_fixed_10_20(float x, float y) { + return !(x >= y) ? 10 : 20; + } + @DontCompile + public static int golden_float_BoolTest_ge_fixed_10_20(float x, float y) { + return !(x >= y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_fixed_10_20(double x, double y) { + return !(x >= y) ? 10 : 20; + } + @DontCompile + public static int golden_double_BoolTest_ge_fixed_10_20(double x, double y) { + return !(x >= y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge_variable_results(float x, float y, int a, int b) { + return !(x >= y) ? a : b; + } + @DontCompile + public static int golden_float_BoolTest_ge_variable_results(float x, float y, int a, int b) { + return !(x >= y) ? a : b; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge_variable_results(double x, double y, int a, int b) { + return !(x >= y) ? a : b; + } + @DontCompile + public static int golden_double_BoolTest_ge_variable_results(double x, double y, int a, int b) { + return !(x >= y) ? a : b; + } + + @Run(test = {"test_float_BoolTest_ge_fixed_1_0", "test_double_BoolTest_ge_fixed_1_0", + "test_float_BoolTest_ge_fixed_0_1", "test_double_BoolTest_ge_fixed_0_1", + "test_float_BoolTest_ge_fixed_10_20", "test_double_BoolTest_ge_fixed_10_20", + "test_float_BoolTest_ge_variable_results", "test_double_BoolTest_ge_variable_results"}) + public void runTests() { + int err = 0; + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_1_0(x, y); + int expected = golden_float_BoolTest_ge_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Float failed (ge), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_1_0(x, y); + int expected = golden_double_BoolTest_ge_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Double failed (ge), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_0_1(x, y); + int expected = golden_float_BoolTest_ge_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Float failed (ge, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_0_1(x, y); + int expected = golden_double_BoolTest_ge_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Double failed (ge, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_ge_fixed_10_20(x, y); + int expected = golden_float_BoolTest_ge_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Float failed (ge, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_ge_fixed_10_20(x, y); + int expected = golden_double_BoolTest_ge_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Double failed (ge, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_float_BoolTest_ge_variable_results(x, y, a, b); + int expected = golden_float_BoolTest_ge_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Float failed (ge), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_double_BoolTest_ge_variable_results(x, y, a, b); + int expected = golden_double_BoolTest_ge_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Double failed (ge), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + if (err != 0) { + throw new RuntimeException("Some tests failed"); + } + } +} + +class Test_gt_1 { + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_1_0(float x, float y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x >= y + // return 0 + // when neither is NaN, and x < y + return !(x < y) ? 1 : 0; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_1_0(float x, float y) { + return !(x < y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_1_0(double x, double y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x >= y + // return 0 + // when neither is NaN, and x < y + return !(x < y) ? 1 : 0; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_1_0(double x, double y) { + return !(x < y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_0_1(float x, float y) { + return !(x < y) ? 0 : 1; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_0_1(float x, float y) { + return !(x < y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_0_1(double x, double y) { + return !(x < y) ? 0 : 1; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_0_1(double x, double y) { + return !(x < y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_10_20(float x, float y) { + return !(x < y) ? 10 : 20; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_10_20(float x, float y) { + return !(x < y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_10_20(double x, double y) { + return !(x < y) ? 10 : 20; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_10_20(double x, double y) { + return !(x < y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_variable_results(float x, float y, int a, int b) { + return !(x < y) ? a : b; + } + @DontCompile + public static int golden_float_BoolTest_gt_variable_results(float x, float y, int a, int b) { + return !(x < y) ? a : b; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_variable_results(double x, double y, int a, int b) { + return !(x < y) ? a : b; + } + @DontCompile + public static int golden_double_BoolTest_gt_variable_results(double x, double y, int a, int b) { + return !(x < y) ? a : b; + } + + @Run(test = {"test_float_BoolTest_gt_fixed_1_0", "test_double_BoolTest_gt_fixed_1_0", + "test_float_BoolTest_gt_fixed_0_1", "test_double_BoolTest_gt_fixed_0_1", + "test_float_BoolTest_gt_fixed_10_20", "test_double_BoolTest_gt_fixed_10_20", + "test_float_BoolTest_gt_variable_results", "test_double_BoolTest_gt_variable_results"}) + public void runTests() { + int err = 0; + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_1_0(x, y); + int expected = golden_float_BoolTest_gt_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Float failed (gt), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_1_0(x, y); + int expected = golden_double_BoolTest_gt_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_0_1(x, y); + int expected = golden_float_BoolTest_gt_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Float failed (gt, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_0_1(x, y); + int expected = golden_double_BoolTest_gt_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Double failed (gt, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_10_20(x, y); + int expected = golden_float_BoolTest_gt_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Float failed (gt, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_10_20(x, y); + int expected = golden_double_BoolTest_gt_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Double failed (gt, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_float_BoolTest_gt_variable_results(x, y, a, b); + int expected = golden_float_BoolTest_gt_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Float failed (gt), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_double_BoolTest_gt_variable_results(x, y, a, b); + int expected = golden_double_BoolTest_gt_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + if (err != 0) { + throw new RuntimeException("Some tests failed"); + } + } +} + +class Test_gt_2 { + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_1_0(float x, float y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x <= y + // return 0 + // when neither is NaN, and x > y + return !(x > y) ? 1 : 0; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_1_0(float x, float y) { + return !(x > y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_1_0(double x, double y) { + // return 1 + // when either x or y is NaN + // when neither is NaN, and x <= y + // return 0 + // when neither is NaN, and x > y + return !(x > y) ? 1 : 0; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_1_0(double x, double y) { + return !(x > y) ? 1 : 0; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_0_1(float x, float y) { + return !(x > y) ? 0 : 1; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_0_1(float x, float y) { + return !(x > y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_0_1(double x, double y) { + return !(x > y) ? 0 : 1; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_0_1(double x, double y) { + return !(x > y) ? 0 : 1; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_fixed_10_20(float x, float y) { + return !(x > y) ? 10 : 20; + } + @DontCompile + public static int golden_float_BoolTest_gt_fixed_10_20(float x, float y) { + return !(x > y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_fixed_10_20(double x, double y) { + return !(x > y) ? 10 : 20; + } + @DontCompile + public static int golden_double_BoolTest_gt_fixed_10_20(double x, double y) { + return !(x > y) ? 10 : 20; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_gt_variable_results(float x, float y, int a, int b) { + return !(x > y) ? a : b; + } + @DontCompile + public static int golden_float_BoolTest_gt_variable_results(float x, float y, int a, int b) { + return !(x > y) ? a : b; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt_variable_results(double x, double y, int a, int b) { + return !(x > y) ? a : b; + } + @DontCompile + public static int golden_double_BoolTest_gt_variable_results(double x, double y, int a, int b) { + return !(x > y) ? a : b; + } + + @Run(test = {"test_float_BoolTest_gt_fixed_1_0", "test_double_BoolTest_gt_fixed_1_0", + "test_float_BoolTest_gt_fixed_0_1", "test_double_BoolTest_gt_fixed_0_1", + "test_float_BoolTest_gt_fixed_10_20", "test_double_BoolTest_gt_fixed_10_20", + "test_float_BoolTest_gt_variable_results", "test_double_BoolTest_gt_variable_results"}) + public void runTests() { + int err = 0; + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_1_0(x, y); + int expected = golden_float_BoolTest_gt_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Float failed (gt), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_1_0(x, y); + int expected = golden_double_BoolTest_gt_fixed_1_0(x, y); + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_0_1(x, y); + int expected = golden_float_BoolTest_gt_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Float failed (gt, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_0_1(x, y); + int expected = golden_double_BoolTest_gt_fixed_0_1(x, y); + if (actual != expected) { + System.out.println("Double failed (gt, 0, 1), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + int actual = test_float_BoolTest_gt_fixed_10_20(x, y); + int expected = golden_float_BoolTest_gt_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Float failed (gt, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + int actual = test_double_BoolTest_gt_fixed_10_20(x, y); + int expected = golden_double_BoolTest_gt_fixed_10_20(x, y); + if (actual != expected) { + System.out.println("Double failed (gt, 10, 20), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + for (int i = 0; i < TestFPComparison2.FLOATS.length; i++) { + for (int j = 0; j < TestFPComparison2.FLOATS.length; j++) { + float x = TestFPComparison2.FLOATS[i]; + float y = TestFPComparison2.FLOATS[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_float_BoolTest_gt_variable_results(x, y, a, b); + int expected = golden_float_BoolTest_gt_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Float failed (gt), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + for (int i = 0; i < TestFPComparison2.DOUBLES.length; i++) { + for (int j = 0; j < TestFPComparison2.DOUBLES.length; j++) { + double x = TestFPComparison2.DOUBLES[i]; + double y = TestFPComparison2.DOUBLES[j]; + for (int m = 0; m < TestFPComparison2.INTS.length; m++) { + for (int n = 0; n < TestFPComparison2.INTS.length; n++) { + int a = TestFPComparison2.INTS[m]; + int b = TestFPComparison2.INTS[n]; + int actual = test_double_BoolTest_gt_variable_results(x, y, a, b); + int expected = golden_double_BoolTest_gt_variable_results(x, y, a, b); + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + ", a: " + a + ", b: " + b + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + } + } + + if (err != 0) { + throw new RuntimeException("Some tests failed"); + } + } +}