From 4bcd6597a33c86615059873504b3140f49c3b96c Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Fri, 17 Feb 2017 16:00:37 +0100 Subject: [PATCH] rs6000: Fix extendsfdf2 for signaling NaNs A cast from float to double should turn a signaling NaN into a quiet NaN, if using -fsignaling-nans. On PowerPC single-precision floats are stored as double precision in registers, and so, the cast normally does nothing. This causes gcc.dg/pr59833.c to fail (it does such a cast, and expects a quiet NaN as output). This patch adds a new pattern, used with -fsignaling-nans in effect, that creates an frsp instruction (or xsrsp) in this case. Since the input already is SFmode, that instruction turns signaling NaNs into quiet NaNs and does nothing more. * config/rs6000/rs6000.md (extendsfdf2): Remove default arguments. If HONOR_SNANS (SFmode) force the input to a register. (*extendsfdf2_fpr): Add !HONOR_SNANS (SFmode) condition. (*extendsfdf2_snan): New pattern, used when using SNaNs; it generates an frsp or similar insn. From-SVN: r245534 --- gcc/ChangeLog | 8 ++++++++ gcc/config/rs6000/rs6000.md | 22 ++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2960c7d284b..0339ac9c5d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-02-17 Segher Boessenkool + + * config/rs6000/rs6000.md (extendsfdf2): Remove default arguments. + If HONOR_SNANS (SFmode) force the input to a register. + (*extendsfdf2_fpr): Add !HONOR_SNANS (SFmode) condition. + (*extendsfdf2_snan): New pattern, used when using SNaNs; it generates + an frsp or similar insn. + 2017-02-17 Martin Liska PR rtl-optimization/79577 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index fca6de04b4c..58e63c18f00 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -4648,15 +4648,19 @@ ;; Floating point conversions (define_expand "extendsfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] + [(set (match_operand:DF 0 "gpc_reg_operand") + (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))] "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") +{ + if (HONOR_SNANS (SFmode)) + operands[1] = force_reg (SFmode, operands[1]); +}) (define_insn_and_split "*extendsfdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !HONOR_SNANS (SFmode)" "@ # fmr %0,%1 @@ -4673,6 +4677,16 @@ } [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) +(define_insn "*extendsfdf2_snan" + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") + (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && HONOR_SNANS (SFmode)" + "@ + frsp %0,%1 + xsrsp %x0,%x1" + [(set_attr "type" "fp")]) + (define_expand "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] -- 2.30.2