RISC-V: Adjust floating point code gen for LTGT compare

Message ID 20200219052945.114917-1-kito.cheng@sifive.com
State New
Headers show
Series
  • RISC-V: Adjust floating point code gen for LTGT compare
Related show

Commit Message

Kito Cheng Feb. 19, 2020, 5:29 a.m.
- Using gcc.dg/torture/pr91323.c as testcase, so no new testcase
   introduced.

 - We use 3 eq compare for LTGT compare before, in order to prevent exception
   flags setting when any input is NaN.

 - According latest GCC document LTGT and discussion on pr91323
   LTGT should signals on NaNs, like GE/GT/LE/LT.

 - So we expand (LTGT a b) to ((LT a b) | (GT a b)) for fit the document.

 - Tested rv64gc/rv32gc bare-metal/linux on qemu and
   rv64gc on HiFive unleashed board with linux.

ChangeLog

gcc/

Kito Cheng  <kito.cheng@sifive.com>

	* config/riscv/riscv.c (riscv_emit_float_compare): Change the code gen
	for LTGT.
---
 gcc/config/riscv/riscv.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

-- 
2.25.0

Comments

Jim Wilson Feb. 19, 2020, 11:44 p.m. | #1
On Tue, Feb 18, 2020 at 9:29 PM Kito Cheng <kito.cheng@sifive.com> wrote:
>         * config/riscv/riscv.c (riscv_emit_float_compare): Change the code gen

>         for LTGT.


I think you should update riscv_rtx_costs also.  The comment is now
wrong for LTGT, and the cost calculation is wrong too.  Looks like it
should be fp_add + COSTS_N_INSNS (2) now.  Otherwise this patch looks
right to me.

Jim

Patch

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 54de0a667a4..5ef74acb56d 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -2239,9 +2239,8 @@  riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
       break;
 
     case UNEQ:
-    case LTGT:
       /* ordered(a, b) > (a == b) */
-      *code = fp_code == LTGT ? GTU : EQ;
+      *code = EQ;
       tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
       tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
       *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
@@ -2293,6 +2292,13 @@  riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
       *op1 = const0_rtx;
       break;
 
+    case LTGT:
+      /* (a < b) | (a > b) */
+      *code = IOR;
+      *op0 = riscv_force_binary (word_mode, LT, cmp_op0, cmp_op1);
+      *op1 = riscv_force_binary (word_mode, GT, cmp_op0, cmp_op1);
+      break;
+
     default:
       gcc_unreachable ();
     }