From 8367c996e55b2c54aeee25e446357a1015a1d11d Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 2 May 2024 17:13:12 -0600 Subject: [PATCH] [committed][RISC-V] Fix nearbyint failure on rv32 and formatting nits The CI system tripped an execution failure for rv32 with the ceil/round patch. The fundamental problem is the FP->INT step in these sequences requires the input size to match the output size. The output size was based on rv32/rv64. Meaning that we'd try to do DF->SI->DF. That doesn't preserve the semantics we want in at least two ways. The net is we can't use this trick for DF values on rv32. While inside the code I realized we had a similar problem for HF modes. HF modes we can support only for Zfa. So I fixed that proactively. The CI system also pointed out various formatting nits. I think this fixes all but one overly long line. Note I could have factored the TARGET_ZFA test. But I think as-written it's clearer what the desired cases to transform are. gcc/ * config/riscv/riscv.md (2): Adjust condition to match what can be properly implemented. Fix various formatting issues. (lsi2_sext): Fix formatting --- gcc/config/riscv/riscv.md | 65 ++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index b9b0acf92c7..d4676507b45 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -2077,8 +2077,8 @@ (define_insn "lsi2_sext" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (unspec:SI - [(match_operand:ANYF 1 "register_operand" " f")] - ROUND)))] + [(match_operand:ANYF 1 "register_operand" " f")] + ROUND)))] "TARGET_64BIT && (TARGET_HARD_FLOAT || TARGET_ZFINX)" "fcvt.w. %0,%1," [(set_attr "type" "fcvt_f2i") @@ -2094,13 +2094,25 @@ [(set_attr "type" "fcvt_f2i") (set_attr "mode" "")]) +;; There are a couple non-obvious restrictions to be aware of. +;; +;; We'll do a FP-INT conversion in the sequence. But we don't +;; have a .l (64bit) variant of those instructions for rv32. +;; To preserve proper semantics we must reject DFmode inputs +;; for rv32 unless Zfa is enabled. +;; +;; The ANYF iterator allows HFmode. We don't have all the +;; necessary patterns defined for HFmode. So restrict HFmode +;; to TARGET_ZFA. (define_expand "2" [(set (match_operand:ANYF 0 "register_operand" "=f") - (unspec:ANYF - [(match_operand:ANYF 1 "register_operand" " f")] - ROUND))] - "TARGET_HARD_FLOAT && (TARGET_ZFA - || flag_fp_int_builtin_inexact || !flag_trapping_math)" + (unspec:ANYF + [(match_operand:ANYF 1 "register_operand" " f")] + ROUND))] + "(TARGET_HARD_FLOAT + && (TARGET_ZFA || flag_fp_int_builtin_inexact || !flag_trapping_math) + && (TARGET_ZFA || TARGET_64BIT || mode != DFmode) + && (TARGET_ZFA || mode != HFmode))" { if (TARGET_ZFA) emit_insn (gen__zfa2 (operands[0], @@ -2116,7 +2128,7 @@ riscv_emit_move (tmp_reg, operands[1]); riscv_emit_move (coeff_reg, - riscv_vector::get_fp_rounding_coefficient (mode)); + riscv_vector::get_fp_rounding_coefficient (mode)); emit_insn (gen_abs2 (abs_reg, operands[1])); riscv_expand_conditional_branch (label, LT, abs_reg, coeff_reg); @@ -2126,29 +2138,20 @@ emit_label (label); switch (mode) - { - case SFmode: - reg = gen_reg_rtx (SImode); - emit_insn (gen_lsfsi2 (reg, operands[1])); - emit_insn (gen_floatsisf2 (abs_reg, reg)); - break; - case DFmode: - if (TARGET_64BIT) - { - reg = gen_reg_rtx (DImode); - emit_insn (gen_ldfdi2 (reg, operands[1])); - emit_insn (gen_floatdidf2 (abs_reg, reg)); - } - else - { - reg = gen_reg_rtx (SImode); - emit_insn (gen_ldfsi2 (reg, operands[1])); - emit_insn (gen_floatsidf2 (abs_reg, reg)); - } - break; - default: - gcc_unreachable (); - } + { + case SFmode: + reg = gen_reg_rtx (SImode); + emit_insn (gen_lsfsi2 (reg, operands[1])); + emit_insn (gen_floatsisf2 (abs_reg, reg)); + break; + case DFmode: + reg = gen_reg_rtx (DImode); + emit_insn (gen_ldfdi2 (reg, operands[1])); + emit_insn (gen_floatdidf2 (abs_reg, reg)); + break; + default: + gcc_unreachable (); + } emit_insn (gen_copysign3 (tmp_reg, abs_reg, operands[1]));