This makes -fsignaling-nans work correctly, fixing 20 glibc testsuite failures. The FP quiet compare pattern is ignoring all exceptions, including for SNaNs. To make this work right when -fsignaling-nan, we need an extra eq compare to raise an exception, but only when HONOR_SNANS is true. So we get the more efficient code in the default case, and code that works for the glibc testsuite when -fsignaling-nans is used.
This was tested with cross riscv32-elf and riscv64-linux builds and checks. It was also tested with a riscv64-linux glibc build and check gcc/ * config/riscv/riscv.md (f<quiet_pattern>_quiet<ANYF:mode><X:mode>4): Add define_expand. Add ! HONOR_SNANS check to current pattern. Add new pattern using HONOR_SNANS that emits one extra instruction. --- gcc/config/riscv/riscv.md | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4162dc578e8..b6c20230ffd 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1957,19 +1957,41 @@ [(set_attr "type" "fcmp") (set_attr "mode" "<UNITMODE>")]) -(define_insn "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4" - [(set (match_operand:X 0 "register_operand" "=r") +(define_expand "f<quiet_pattern>_quiet<ANYF:mode><X:mode>4" + [(parallel [(set (match_operand:X 0 "register_operand") + (unspec:X + [(match_operand:ANYF 1 "register_operand") + (match_operand:ANYF 2 "register_operand")] + QUIET_COMPARISON)) + (clobber (match_scratch:X 3))])] + "TARGET_HARD_FLOAT") + +(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_default" + [(set (match_operand:X 0 "register_operand" "=r") (unspec:X - [(match_operand:ANYF 1 "register_operand" " f") - (match_operand:ANYF 2 "register_operand" " f")] - QUIET_COMPARISON)) + [(match_operand:ANYF 1 "register_operand" " f") + (match_operand:ANYF 2 "register_operand" " f")] + QUIET_COMPARISON)) (clobber (match_scratch:X 3 "=&r"))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && ! HONOR_SNANS (<ANYF:MODE>mode)" "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3" [(set_attr "type" "fcmp") (set_attr "mode" "<UNITMODE>") (set (attr "length") (const_int 12))]) +(define_insn "*f<quiet_pattern>_quiet<ANYF:mode><X:mode>4_snan" + [(set (match_operand:X 0 "register_operand" "=r") + (unspec:X + [(match_operand:ANYF 1 "register_operand" " f") + (match_operand:ANYF 2 "register_operand" " f")] + QUIET_COMPARISON)) + (clobber (match_scratch:X 3 "=&r"))] + "TARGET_HARD_FLOAT && HONOR_SNANS (<ANYF:MODE>mode)" + "frflags\t%3\n\tf<quiet_pattern>.<fmt>\t%0,%1,%2\n\tfsflags %3\n\tfeq.<fmt>\tzero,%1,%2" + [(set_attr "type" "fcmp") + (set_attr "mode" "<UNITMODE>") + (set (attr "length") (const_int 16))]) + (define_insn "*seq_zero_<X:mode><GPR:mode>" [(set (match_operand:GPR 0 "register_operand" "=r") (eq:GPR (match_operand:X 1 "register_operand" " r") -- 2.17.1