From 9069e9484cec2ff981c87c75b226ad738847ca07 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Mon, 24 Feb 2020 10:54:21 -0600 Subject: [PATCH] RISC-V: Adjust floating point code gen for LTGT compare - 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 * config/riscv/riscv.c (riscv_emit_float_compare): Change the code gen for LTGT. (riscv_rtx_costs): Update cost model for LTGT. --- gcc/ChangeLog | 6 ++++++ gcc/config/riscv/riscv.c | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b3b9d92..49986c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-24 Kito Cheng + + * config/riscv/riscv.c (riscv_emit_float_compare): Change the code gen + for LTGT. + (riscv_rtx_costs): Update cost model for LTGT. + 2020-02-23 Vladimir Makarov PR rtl-optimization/93564 diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 54de0a6..d45b19d 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -1703,12 +1703,17 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN return false; case UNEQ: - case LTGT: /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */ mode = GET_MODE (XEXP (x, 0)); *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (3); return false; + case LTGT: + /* (FLT(A, A) || FGT(B, B)). */ + mode = GET_MODE (XEXP (x, 0)); + *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (2); + return false; + case UNGE: case UNGT: case UNLE: @@ -2239,9 +2244,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 +2297,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 (); } -- 2.7.4