From e5b06b5621b01dbb557fc21881307c9131f4bb53 Mon Sep 17 00:00:00 2001 From: hamlin Date: Mon, 9 Jun 2025 15:54:12 +0000 Subject: [PATCH 01/15] initial commit --- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 77b4e26cc924b..639c23a42c79f 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_le(op2, op1, 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_lt(op2, op1, dst, src, is_single); break; default: assert(false, "unsupported compare condition"); From 2d714f8f198f010ac85aed77d1b0d562d51ebfb6 Mon Sep 17 00:00:00 2001 From: hamlin Date: Tue, 10 Jun 2025 16:04:04 +0000 Subject: [PATCH 02/15] fix BoolTest::ge/gt --- .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 8 ++- .../cpu/riscv/macroAssembler_riscv.cpp | 64 +++++++++++++++++++ .../cpu/riscv/macroAssembler_riscv.hpp | 2 + 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 639c23a42c79f..0aa6bb62a5a2b 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2170,13 +2170,17 @@ 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: - cmov_cmp_fp_le(op2, op1, dst, src, is_single); + // This log is for JDK-8358892 + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"); + 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: - cmov_cmp_fp_lt(op2, op1, dst, src, is_single); + // This log is for JDK-8358892 + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"); + cmov_cmp_fp_gt(op2, op1, 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..0e5a8ed58038a 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1359,6 +1359,38 @@ 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 = dst, otherwise, dst = src +// Clarification +// scenario 1: +// java code : !(cmp2 >= cmp1) ? dst : src +// transformed to : CMove dst, (cmp1 ge cmp2), dst, src +// scenario 2: +// java code : !(cmp1 <= cmp2) ? dst : src +// transformed to : CMove dst, (cmp1 ge 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 + // not jump (i.e. move src to dst) if cmp1 >= cmp2 + float_blt(cmp1, cmp2, no_set, false, true); + } else { + double_blt(cmp1, cmp2, no_set, false, true); + } + mv(dst, src); + bind(no_set); +} + // When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst // Clarification // scenario 1: @@ -1391,6 +1423,38 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi bind(no_set); } +// When cmp1 >= cmp2 or any of them is NaN then dst = dst, otherwise, dst = src +// Clarification +// scenario 1: +// java code : cmp2 > cmp1 ? dst : src +// transformed to : CMove dst, (cmp1 gt cmp2), dst, src +// scenario 2: +// java code : cmp1 < cmp2 ? dst : src +// transformed to : CMove dst, (cmp1 gt cmp2), dst, src +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, cmp1, cmp2); + } else { + flt_d(t0, cmp1, cmp2); + } + 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 + // not jump (i.e. move src to dst) if cmp1 < cmp2 + float_bge(cmp1, cmp2, no_set, false, true); + } else { + double_bge(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. From 45dc49497a0492c89f9f98bce657c5a120dc152e Mon Sep 17 00:00:00 2001 From: hamlin Date: Tue, 10 Jun 2025 16:04:27 +0000 Subject: [PATCH 03/15] tests --- .../c2/irTests/TestFPComparison2.java | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java 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..8f98991b208a5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -0,0 +1,361 @@ +/* + * 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 jdk.test.lib.Asserts; + +/* + * @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" + * @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, + }; + + public static void main(String[] args) { + // Booltest::ge + TestFramework framework = new TestFramework(Test_ge_1.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), + "Not trigger BoolTest::ge"); + + framework = new TestFramework(Test_ge_1.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), + "Not trigger BoolTest::ge"); + + framework = new TestFramework(Test_ge_2.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), + "Not trigger BoolTest::ge"); + + framework = new TestFramework(Test_ge_2.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), + "Not trigger BoolTest::ge"); + + // Booltest::gt + framework = new TestFramework(Test_gt_1.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), + "Not trigger BoolTest::gt"); + + framework = new TestFramework(Test_gt_1.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), + "Not trigger BoolTest::gt"); + + framework = new TestFramework(Test_gt_2.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), + "Not trigger BoolTest::gt"); + + framework = new TestFramework(Test_gt_2.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") + .start(); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), + "Not trigger BoolTest::gt"); + } +} + +class Test_ge_1 { + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_float_BoolTest_ge(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; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge(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; + } + + @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) + 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(x, y); + int expected = !(x <= y) ? 1 : 0; + 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(x, y); + int expected = !(x <= y) ? 1 : 0; + if (actual != expected) { + System.out.println("Double failed (ge), x: " + x + ", y: " + y + + ", 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(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; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_ge(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; + } + + @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) + 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(x, y); + int expected = !(x >= y) ? 1 : 0; + 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(x, y); + int expected = !(x >= y) ? 1 : 0; + if (actual != expected) { + System.out.println("Double failed (ge), x: " + x + ", y: " + y + + ", 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(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; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt(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; + } + + @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) + 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(x, y); + int expected = !(x < y) ? 1 : 0; + 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(x, y); + int expected = !(x < y) ? 1 : 0; + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + + ", 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(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; + } + + @Test + @IR(counts = {IRNode.CMOVE_I, "1"}) + public static int test_double_BoolTest_gt(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; + } + + @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) + 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(x, y); + int expected = !(x > y) ? 1 : 0; + 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(x, y); + int expected = !(x > y) ? 1 : 0; + if (actual != expected) { + System.out.println("Double failed (gt), x: " + x + ", y: " + y + + ", actual: " + actual + ", expected: " + expected); + err++; + } + } + } + + if (err != 0) { + throw new RuntimeException("Some tests failed"); + } + } +} From 7da631b8d18d5cffb4de250089e468731b8888f2 Mon Sep 17 00:00:00 2001 From: hamlin Date: Tue, 10 Jun 2025 16:10:36 +0000 Subject: [PATCH 04/15] typo --- .../compiler/c2/irTests/TestFPComparison2.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index 8f98991b208a5..b202f9fa6fea0 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -183,9 +183,9 @@ class Test_ge_2 { public static int test_float_BoolTest_ge(float x, float y) { // return 1 // when either x or y is NaN - // when neither is NaN, and x > y + // when neither is NaN, and x < y // return 0 - // when neither is NaN, and x <= y + // when neither is NaN, and x >= y return !(x >= y) ? 1 : 0; } @@ -194,9 +194,9 @@ public static int test_float_BoolTest_ge(float x, float y) { public static int test_double_BoolTest_ge(double x, double y) { // return 1 // when either x or y is NaN - // when neither is NaN, and x > y + // when neither is NaN, and x < y // return 0 - // when neither is NaN, and x <= y + // when neither is NaN, and x >= y return !(x >= y) ? 1 : 0; } @@ -305,9 +305,9 @@ class Test_gt_2 { public static int test_float_BoolTest_gt(float x, float y) { // return 1 // when either x or y is NaN - // when neither is NaN, and x >= y + // when neither is NaN, and x <= y // return 0 - // when neither is NaN, and x < y + // when neither is NaN, and x > y return !(x > y) ? 1 : 0; } @@ -316,9 +316,9 @@ public static int test_float_BoolTest_gt(float x, float y) { public static int test_double_BoolTest_gt(double x, double y) { // return 1 // when either x or y is NaN - // when neither is NaN, and x >= y + // when neither is NaN, and x <= y // return 0 - // when neither is NaN, and x < y + // when neither is NaN, and x > y return !(x > y) ? 1 : 0; } From 73e81209233aaea88cfcc171520485396ba19cf5 Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 11 Jun 2025 09:05:47 +0000 Subject: [PATCH 05/15] debug --- .../c2/irTests/TestFPComparison2.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index b202f9fa6fea0..3f195b370c06b 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -31,6 +31,7 @@ * @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 */ @@ -66,53 +67,45 @@ public class TestFPComparison2 { public static void main(String[] args) { // Booltest::ge TestFramework framework = new TestFramework(Test_ge_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); framework = new TestFramework(Test_ge_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); framework = new TestFramework(Test_ge_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); + "Not trigger BoolTest::ge"); framework = new TestFramework(Test_ge_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); + "Not trigger BoolTest::ge"); // Booltest::gt framework = new TestFramework(Test_gt_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); framework = new TestFramework(Test_gt_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); framework = new TestFramework(Test_gt_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); + "Not trigger BoolTest::gt"); framework = new TestFramework(Test_gt_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace") - .start(); + framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); + "Not trigger BoolTest::gt"); } } From 423cf1cce79507111525123e245cbfce772c8073 Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 11 Jun 2025 09:19:40 +0000 Subject: [PATCH 06/15] golden values --- .../c2/irTests/TestFPComparison2.java | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index 3f195b370c06b..f64e39905c943 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -120,6 +120,10 @@ public static int test_float_BoolTest_ge(float x, float y) { // when neither is NaN, and x <= y return !(x <= y) ? 1 : 0; } + @DontCompile + public static int golden_float_BoolTest_ge(float x, float y) { + return !(x <= y) ? 1 : 0; + } @Test @IR(counts = {IRNode.CMOVE_I, "1"}) @@ -131,6 +135,10 @@ public static int test_double_BoolTest_ge(double x, double y) { // when neither is NaN, and x <= y return !(x <= y) ? 1 : 0; } + @DontCompile + public static int golden_double_BoolTest_ge(double x, double y) { + return !(x <= y) ? 1 : 0; + } @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) public void runTests() { @@ -141,7 +149,7 @@ public void runTests() { float x = TestFPComparison2.FLOATS[i]; float y = TestFPComparison2.FLOATS[j]; int actual = test_float_BoolTest_ge(x, y); - int expected = !(x <= y) ? 1 : 0; + int expected = golden_float_BoolTest_ge(x, y); if (actual != expected) { System.out.println("Float failed (ge), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -155,7 +163,7 @@ public void runTests() { double x = TestFPComparison2.DOUBLES[i]; double y = TestFPComparison2.DOUBLES[j]; int actual = test_double_BoolTest_ge(x, y); - int expected = !(x <= y) ? 1 : 0; + int expected = golden_double_BoolTest_ge(x, y); if (actual != expected) { System.out.println("Double failed (ge), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -181,6 +189,10 @@ public static int test_float_BoolTest_ge(float x, float y) { // when neither is NaN, and x >= y return !(x >= y) ? 1 : 0; } + @DontCompile + public static int golden_float_BoolTest_ge(float x, float y) { + return !(x >= y) ? 1 : 0; + } @Test @IR(counts = {IRNode.CMOVE_I, "1"}) @@ -192,6 +204,10 @@ public static int test_double_BoolTest_ge(double x, double y) { // when neither is NaN, and x >= y return !(x >= y) ? 1 : 0; } + @DontCompile + public static int golden_double_BoolTest_ge(double x, double y) { + return !(x >= y) ? 1 : 0; + } @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) public void runTests() { @@ -202,7 +218,7 @@ public void runTests() { float x = TestFPComparison2.FLOATS[i]; float y = TestFPComparison2.FLOATS[j]; int actual = test_float_BoolTest_ge(x, y); - int expected = !(x >= y) ? 1 : 0; + int expected = golden_float_BoolTest_ge(x, y); if (actual != expected) { System.out.println("Float failed (ge), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -216,7 +232,7 @@ public void runTests() { double x = TestFPComparison2.DOUBLES[i]; double y = TestFPComparison2.DOUBLES[j]; int actual = test_double_BoolTest_ge(x, y); - int expected = !(x >= y) ? 1 : 0; + int expected = golden_double_BoolTest_ge(x, y); if (actual != expected) { System.out.println("Double failed (ge), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -242,6 +258,10 @@ public static int test_float_BoolTest_gt(float x, float y) { // when neither is NaN, and x < y return !(x < y) ? 1 : 0; } + @DontCompile + public static int golden_float_BoolTest_gt(float x, float y) { + return !(x < y) ? 1 : 0; + } @Test @IR(counts = {IRNode.CMOVE_I, "1"}) @@ -253,6 +273,10 @@ public static int test_double_BoolTest_gt(double x, double y) { // when neither is NaN, and x < y return !(x < y) ? 1 : 0; } + @DontCompile + public static int golden_double_BoolTest_gt(double x, double y) { + return !(x < y) ? 1 : 0; + } @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) public void runTests() { @@ -263,7 +287,7 @@ public void runTests() { float x = TestFPComparison2.FLOATS[i]; float y = TestFPComparison2.FLOATS[j]; int actual = test_float_BoolTest_gt(x, y); - int expected = !(x < y) ? 1 : 0; + int expected = golden_float_BoolTest_gt(x, y); if (actual != expected) { System.out.println("Float failed (gt), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -277,7 +301,7 @@ public void runTests() { double x = TestFPComparison2.DOUBLES[i]; double y = TestFPComparison2.DOUBLES[j]; int actual = test_double_BoolTest_gt(x, y); - int expected = !(x < y) ? 1 : 0; + int expected = golden_double_BoolTest_gt(x, y); if (actual != expected) { System.out.println("Double failed (gt), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -303,6 +327,10 @@ public static int test_float_BoolTest_gt(float x, float y) { // when neither is NaN, and x > y return !(x > y) ? 1 : 0; } + @DontCompile + public static int golden_float_BoolTest_gt(float x, float y) { + return !(x > y) ? 1 : 0; + } @Test @IR(counts = {IRNode.CMOVE_I, "1"}) @@ -314,6 +342,10 @@ public static int test_double_BoolTest_gt(double x, double y) { // when neither is NaN, and x > y return !(x > y) ? 1 : 0; } + @DontCompile + public static int golden_double_BoolTest_gt(double x, double y) { + return !(x > y) ? 1 : 0; + } @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) public void runTests() { @@ -324,7 +356,7 @@ public void runTests() { float x = TestFPComparison2.FLOATS[i]; float y = TestFPComparison2.FLOATS[j]; int actual = test_float_BoolTest_gt(x, y); - int expected = !(x > y) ? 1 : 0; + int expected = golden_float_BoolTest_gt(x, y); if (actual != expected) { System.out.println("Float failed (gt), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); @@ -338,7 +370,7 @@ public void runTests() { double x = TestFPComparison2.DOUBLES[i]; double y = TestFPComparison2.DOUBLES[j]; int actual = test_double_BoolTest_gt(x, y); - int expected = !(x > y) ? 1 : 0; + int expected = golden_double_BoolTest_gt(x, y); if (actual != expected) { System.out.println("Double failed (gt), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); From 9848cc28b4e70137e00e62fcf3a2636e3bef008e Mon Sep 17 00:00:00 2001 From: hamlin Date: Wed, 11 Jun 2025 12:46:30 +0000 Subject: [PATCH 07/15] adjust arguments orders --- .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 2 +- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 0aa6bb62a5a2b..bff8655c6922f 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2180,7 +2180,7 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe case BoolTest::gt: // This log is for JDK-8358892 log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"); - cmov_cmp_fp_gt(op2, op1, dst, src, is_single); + 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 0e5a8ed58038a..a113ad5455e7b 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1423,20 +1423,20 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi bind(no_set); } -// When cmp1 >= cmp2 or any of them is NaN then dst = dst, otherwise, dst = src +// When cmp1 <= cmp2 or any of them is NaN then dst = dst, otherwise, dst = src // Clarification // scenario 1: -// java code : cmp2 > cmp1 ? dst : src +// java code : !(cmp2 > cmp1) ? dst : src // transformed to : CMove dst, (cmp1 gt cmp2), dst, src // scenario 2: -// java code : cmp1 < cmp2 ? dst : src +// java code : !(cmp1 < cmp2) ? dst : src // transformed to : CMove dst, (cmp1 gt cmp2), dst, src 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, cmp1, cmp2); + flt_s(t0, cmp2, cmp1); } else { - flt_d(t0, cmp1, cmp2); + flt_d(t0, cmp2, cmp1); } czero_nez(dst, dst, t0); czero_eqz(t0 , src, t0); @@ -1445,11 +1445,11 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi } Label no_set; if (is_single) { - // jump if cmp1 >= cmp2 or either is NaN - // not jump (i.e. move src to dst) if cmp1 < cmp2 - float_bge(cmp1, cmp2, no_set, false, true); + // jump if cmp1 <= cmp2 or either is NaN + // not jump (i.e. move src to dst) if cmp1 > cmp2 + float_ble(cmp1, cmp2, no_set, false, true); } else { - double_bge(cmp1, cmp2, no_set, false, true); + double_ble(cmp1, cmp2, no_set, false, true); } mv(dst, src); bind(no_set); From 852ef94f9ef3e1beddc2f5b8f7e707cb7ec7d19f Mon Sep 17 00:00:00 2001 From: hamlin Date: Thu, 12 Jun 2025 16:47:44 +0000 Subject: [PATCH 08/15] comments --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index a113ad5455e7b..8a2d2ef376a5a 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1289,7 +1289,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); @@ -1318,7 +1318,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); @@ -1350,7 +1350,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); @@ -1382,7 +1382,7 @@ void MacroAssembler::cmov_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 < cmp2 or either is NaN - // not jump (i.e. move src to dst) if cmp1 >= cmp2 + // 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); @@ -1414,7 +1414,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); @@ -1446,7 +1446,7 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi Label no_set; if (is_single) { // jump if cmp1 <= cmp2 or either is NaN - // not jump (i.e. move src to dst) if cmp1 > cmp2 + // 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); From eb38253e94144b481a9da1e7fbfa9b22dfc0f24c Mon Sep 17 00:00:00 2001 From: hamlin Date: Thu, 12 Jun 2025 16:49:39 +0000 Subject: [PATCH 09/15] review Zicond --- .../c2/irTests/TestFPComparison2.java | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index f64e39905c943..472c38e009acc 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -67,43 +67,23 @@ public class TestFPComparison2 { public static void main(String[] args) { // Booltest::ge TestFramework framework = new TestFramework(Test_ge_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); - - framework = new TestFramework(Test_ge_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); - - framework = new TestFramework(Test_ge_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); + framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); framework = new TestFramework(Test_ge_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); + framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); // Booltest::gt framework = new TestFramework(Test_gt_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); - - framework = new TestFramework(Test_gt_1.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); - - framework = new TestFramework(Test_gt_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:+UseZicond", "-Xlog:jit+compilation=trace").start(); + framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); framework = new TestFramework(Test_gt_2.class); - framework.addFlags("-XX:-TieredCompilation", "-XX:-UseZicond", "-Xlog:jit+compilation=trace").start(); + framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); } From 962f49443ee2a72e2ce6f6dd99bb91e556d24933 Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 09:53:50 +0000 Subject: [PATCH 10/15] more tests --- .../c2/irTests/TestFPComparison2.java | 732 +++++++++++++++++- 1 file changed, 690 insertions(+), 42 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index 472c38e009acc..f4abf496b1db0 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -24,6 +24,7 @@ package compiler.c2.irTests; import compiler.lib.ir_framework.*; +import java.util.List; import jdk.test.lib.Asserts; /* @@ -64,26 +65,37 @@ public class TestFPComparison2 { 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("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); + framework.addFlags(options.toArray(new String[0])).start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); framework = new TestFramework(Test_ge_2.class); - framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); + framework.addFlags(options.toArray(new String[0])).start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), "Not trigger BoolTest::ge"); // Booltest::gt framework = new TestFramework(Test_gt_1.class); - framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); + framework.addFlags(options.toArray(new String[0])).start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); framework = new TestFramework(Test_gt_2.class); - framework.addFlags("-XX:-TieredCompilation", "-Xlog:jit+compilation=trace").start(); + framework.addFlags(options.toArray(new String[0])).start(); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), "Not trigger BoolTest::gt"); } @@ -92,7 +104,7 @@ public static void main(String[] args) { class Test_ge_1 { @Test @IR(counts = {IRNode.CMOVE_I, "1"}) - public static int test_float_BoolTest_ge(float x, float y) { + 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 @@ -101,13 +113,13 @@ public static int test_float_BoolTest_ge(float x, float y) { return !(x <= y) ? 1 : 0; } @DontCompile - public static int golden_float_BoolTest_ge(float x, float y) { + 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(double x, double y) { + 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 @@ -116,11 +128,74 @@ public static int test_double_BoolTest_ge(double x, double y) { return !(x <= y) ? 1 : 0; } @DontCompile - public static int golden_double_BoolTest_ge(double x, double y) { + public static int golden_double_BoolTest_ge_fixed_1_0(double x, double y) { return !(x <= y) ? 1 : 0; } - @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) + @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; @@ -128,10 +203,10 @@ public void runTests() { 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(x, y); - int expected = golden_float_BoolTest_ge(x, y); + 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 + + System.out.println("Float failed (ge, 1, 0), x: " + x + ", y: " + y + ", actual: " + actual + ", expected: " + expected); err++; } @@ -142,16 +217,112 @@ public void runTests() { 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(x, y); - int expected = golden_double_BoolTest_ge(x, y); + 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 + + 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"); } @@ -161,7 +332,7 @@ public void runTests() { class Test_ge_2 { @Test @IR(counts = {IRNode.CMOVE_I, "1"}) - public static int test_float_BoolTest_ge(float x, float y) { + 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 @@ -170,13 +341,13 @@ public static int test_float_BoolTest_ge(float x, float y) { return !(x >= y) ? 1 : 0; } @DontCompile - public static int golden_float_BoolTest_ge(float x, float y) { + 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(double x, double y) { + 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 @@ -185,11 +356,74 @@ public static int test_double_BoolTest_ge(double x, double y) { return !(x >= y) ? 1 : 0; } @DontCompile - public static int golden_double_BoolTest_ge(double x, double y) { + public static int golden_double_BoolTest_ge_fixed_1_0(double x, double y) { return !(x >= y) ? 1 : 0; } - @Run(test = {"test_float_BoolTest_ge", "test_double_BoolTest_ge"}) + @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; @@ -197,8 +431,8 @@ public void runTests() { 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(x, y); - int expected = golden_float_BoolTest_ge(x, y); + 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); @@ -211,8 +445,8 @@ public void runTests() { 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(x, y); - int expected = golden_double_BoolTest_ge(x, y); + 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); @@ -221,6 +455,102 @@ public void runTests() { } } + 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"); } @@ -230,7 +560,7 @@ public void runTests() { class Test_gt_1 { @Test @IR(counts = {IRNode.CMOVE_I, "1"}) - public static int test_float_BoolTest_gt(float x, float y) { + 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 @@ -239,13 +569,13 @@ public static int test_float_BoolTest_gt(float x, float y) { return !(x < y) ? 1 : 0; } @DontCompile - public static int golden_float_BoolTest_gt(float x, float y) { + 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(double x, double y) { + 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 @@ -254,11 +584,74 @@ public static int test_double_BoolTest_gt(double x, double y) { return !(x < y) ? 1 : 0; } @DontCompile - public static int golden_double_BoolTest_gt(double x, double y) { + public static int golden_double_BoolTest_gt_fixed_1_0(double x, double y) { return !(x < y) ? 1 : 0; } - @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) + @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; @@ -266,8 +659,8 @@ public void runTests() { 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(x, y); - int expected = golden_float_BoolTest_gt(x, y); + 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); @@ -280,8 +673,8 @@ public void runTests() { 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(x, y); - int expected = golden_double_BoolTest_gt(x, y); + 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); @@ -290,6 +683,102 @@ public void runTests() { } } + 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"); } @@ -299,7 +788,7 @@ public void runTests() { class Test_gt_2 { @Test @IR(counts = {IRNode.CMOVE_I, "1"}) - public static int test_float_BoolTest_gt(float x, float y) { + 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 @@ -308,13 +797,13 @@ public static int test_float_BoolTest_gt(float x, float y) { return !(x > y) ? 1 : 0; } @DontCompile - public static int golden_float_BoolTest_gt(float x, float y) { + 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(double x, double y) { + 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 @@ -323,11 +812,74 @@ public static int test_double_BoolTest_gt(double x, double y) { return !(x > y) ? 1 : 0; } @DontCompile - public static int golden_double_BoolTest_gt(double x, double y) { + public static int golden_double_BoolTest_gt_fixed_1_0(double x, double y) { return !(x > y) ? 1 : 0; } - @Run(test = {"test_float_BoolTest_gt", "test_double_BoolTest_gt"}) + @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; @@ -335,8 +887,8 @@ public void runTests() { 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(x, y); - int expected = golden_float_BoolTest_gt(x, y); + 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); @@ -349,8 +901,8 @@ public void runTests() { 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(x, y); - int expected = golden_double_BoolTest_gt(x, y); + 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); @@ -359,6 +911,102 @@ public void runTests() { } } + 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"); } From d94c6317e7200bd032499767c2b2ec2a8fc950da Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 10:22:22 +0000 Subject: [PATCH 11/15] more log --- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index bff8655c6922f..554052e35af96 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2161,12 +2161,15 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe switch (op_select) { case BoolTest::eq: + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::eq"); cmov_cmp_fp_eq(op1, op2, dst, src, is_single); break; case BoolTest::ne: + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ne"); cmov_cmp_fp_ne(op1, op2, dst, src, is_single); break; case BoolTest::le: + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::le"); cmov_cmp_fp_le(op1, op2, dst, src, is_single); break; case BoolTest::ge: @@ -2175,6 +2178,7 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe cmov_cmp_fp_ge(op1, op2, dst, src, is_single); break; case BoolTest::lt: + log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::lt"); cmov_cmp_fp_lt(op1, op2, dst, src, is_single); break; case BoolTest::gt: From 0f5ca7deb391c1d1bf08b1970a1aa2c1eddec0bb Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 10:54:20 +0000 Subject: [PATCH 12/15] no assert --- .../c2/irTests/TestFPComparison2.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index f4abf496b1db0..6537090070f92 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -25,7 +25,6 @@ import compiler.lib.ir_framework.*; import java.util.List; -import jdk.test.lib.Asserts; /* * @test @@ -80,24 +79,28 @@ public static void main(String[] args) { // Booltest::ge TestFramework framework = new TestFramework(Test_ge_1.class); framework.addFlags(options.toArray(new String[0])).start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); + if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge")) { + System.out.println("====== Not trigger BoolTest::ge"); + } framework = new TestFramework(Test_ge_2.class); framework.addFlags(options.toArray(new String[0])).start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"), - "Not trigger BoolTest::ge"); + if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge")) { + System.out.println("====== Not trigger BoolTest::ge"); + } // Booltest::gt framework = new TestFramework(Test_gt_1.class); framework.addFlags(options.toArray(new String[0])).start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); + if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt")) { + System.out.println("====== Not trigger BoolTest::gt"); + } framework = new TestFramework(Test_gt_2.class); framework.addFlags(options.toArray(new String[0])).start(); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"), - "Not trigger BoolTest::gt"); + if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt")) { + System.out.println("====== Not trigger BoolTest::gt"); + } } } From e6d172f9acd43eef7e5ddaf8a257db16969588b9 Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 12:58:20 +0000 Subject: [PATCH 13/15] refine comments --- .../cpu/riscv/macroAssembler_riscv.cpp | 53 ++++--------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 8a2d2ef376a5a..5575d42de12dd 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1268,12 +1268,18 @@ 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)) +// 1. (op1 lt NaN) => true => CMove: dst = src +// 2. (op1 le NaN) => true => CMove: dst = src +// 3. (op1 gt NaN) => false => CMove: dst = dst +// 4. (op1 ge NaN) => false => CMove: dst = dst +// 5. (op1 eq NaN) => false => CMove: dst = dst +// 6. (op1 ne NaN) => 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) { @@ -1298,11 +1304,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) { @@ -1327,14 +1328,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) { @@ -1359,14 +1352,6 @@ 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 = dst, otherwise, dst = src -// Clarification -// scenario 1: -// java code : !(cmp2 >= cmp1) ? dst : src -// transformed to : CMove dst, (cmp1 ge cmp2), dst, src -// scenario 2: -// java code : !(cmp1 <= cmp2) ? dst : src -// transformed to : CMove dst, (cmp1 ge 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) { @@ -1391,14 +1376,6 @@ void MacroAssembler::cmov_cmp_fp_ge(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_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { @@ -1423,14 +1400,6 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi bind(no_set); } -// When cmp1 <= cmp2 or any of them is NaN then dst = dst, otherwise, dst = src -// Clarification -// scenario 1: -// java code : !(cmp2 > cmp1) ? dst : src -// transformed to : CMove dst, (cmp1 gt cmp2), dst, src -// scenario 2: -// java code : !(cmp1 < cmp2) ? dst : src -// transformed to : CMove dst, (cmp1 gt cmp2), dst, src void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) { if (is_single) { From 7638e272ee64597553e55ea118c4c4fa47ecace0 Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 13:03:07 +0000 Subject: [PATCH 14/15] remove log --- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp | 8 -------- .../jtreg/compiler/c2/irTests/TestFPComparison2.java | 12 ------------ 2 files changed, 20 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 554052e35af96..ce13ebde74f9b 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2161,29 +2161,21 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe switch (op_select) { case BoolTest::eq: - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::eq"); cmov_cmp_fp_eq(op1, op2, dst, src, is_single); break; case BoolTest::ne: - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ne"); cmov_cmp_fp_ne(op1, op2, dst, src, is_single); break; case BoolTest::le: - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::le"); cmov_cmp_fp_le(op1, op2, dst, src, is_single); break; case BoolTest::ge: - // This log is for JDK-8358892 - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge"); cmov_cmp_fp_ge(op1, op2, dst, src, is_single); break; case BoolTest::lt: - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::lt"); cmov_cmp_fp_lt(op1, op2, dst, src, is_single); break; case BoolTest::gt: - // This log is for JDK-8358892 - log_develop_trace(jit, compilation)("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt"); cmov_cmp_fp_gt(op1, op2, dst, src, is_single); break; default: diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java index 6537090070f92..59c70b6873fb4 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFPComparison2.java @@ -79,28 +79,16 @@ public static void main(String[] args) { // Booltest::ge TestFramework framework = new TestFramework(Test_ge_1.class); framework.addFlags(options.toArray(new String[0])).start(); - if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge")) { - System.out.println("====== Not trigger BoolTest::ge"); - } framework = new TestFramework(Test_ge_2.class); framework.addFlags(options.toArray(new String[0])).start(); - if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::ge")) { - System.out.println("====== Not trigger BoolTest::ge"); - } // Booltest::gt framework = new TestFramework(Test_gt_1.class); framework.addFlags(options.toArray(new String[0])).start(); - if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt")) { - System.out.println("====== Not trigger BoolTest::gt"); - } framework = new TestFramework(Test_gt_2.class); framework.addFlags(options.toArray(new String[0])).start(); - if (!TestFramework.getLastTestVMOutput().contains("C2_MacroAssembler::enc_cmove_cmp_fp => BoolTest::gt")) { - System.out.println("====== Not trigger BoolTest::gt"); - } } } From d3dff7950e32481a39c6631e0ad8bf2475edf051 Mon Sep 17 00:00:00 2001 From: hamlin Date: Fri, 13 Jun 2025 13:17:24 +0000 Subject: [PATCH 15/15] comments --- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 5575d42de12dd..12c702b6d1324 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1273,12 +1273,13 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist // so, just list behaviour of unordered ones as follow. // // Set dst (CMoveI (Binary cop (CmpF/D op1 op2)) (Binary dst src)) -// 1. (op1 lt NaN) => true => CMove: dst = src -// 2. (op1 le NaN) => true => CMove: dst = src -// 3. (op1 gt NaN) => false => CMove: dst = dst -// 4. (op1 ge NaN) => false => CMove: dst = dst -// 5. (op1 eq NaN) => false => CMove: dst = dst -// 6. (op1 ne NaN) => true => CMove: 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 void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) { if (UseZicond) {