[Committed] PR target/14888: Provide truncdfsf2_noop implementation

Roger Sayle roger@eyesopen.com
Fri Apr 9 02:15:00 GMT 2004


The following patch resolves PR target/14888 which is an ICE on valid
compiling programs on IA-32 with -ffast-math, which was caused by my
"skip double->float truncation" patch.

I'd originally believed that all FLOAT_TRUNCATE insns would be completely
eliminated by GCC's reg-stack pass, so there was no need to provide an
implementation for the truncdfsf2_noop pattern (and its friends).  Alas
this bugzilla PR shows that all such truncations get eliminated, and
rarely these insns survive until final.

My first attempt at resolving this problem was to tweak reg-stack.c to
be more clever about replacing these pseudo-move instructions with
explicit mov.f2 instructions.  Alas this proved to be trickier than I
thought, as theoretically FLOAT_TRUNCATE can potentially trap if we're
using -fnon-call-exceptions, even though with -ffast-math it really is
just a "noop_move", GCC's machine independent code thinks it can affect
control flow and register liveness.  Dead-end.

The approach below follows the extendsfdf2 patterns in i386.md by
admitting that rarely these patterns are not easily removed, and so
implement them using the standard idiom for implementing FP reg->reg
moves.  This has the advantage over reusing "mov" patterns that it
preserves "type-safety" in the RTL.


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.  Committed to
mainline, my appologies for the inconvenience.

I'm working on a follow-up patch to refactor the duplicated code below
into a "const char *output_fp_reg_move (rtx, rtx)" function, from these
and other patterns in i386.md.



2004-04-08  Roger Sayle  <roger@eyesopen.com>

	PR target/14888
	* config/i386/i386.md (truncdfsf2_noop, truncxfsf2_noop,
	truncxfdf2_noop): Provide dummy "fmov" implementations.

	* g++.dg/opt/pr14888.C: New test case.


Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.524
diff -c -3 -p -r1.524 i386.md
*** config/i386/i386.md	6 Apr 2004 19:34:15 -0000	1.524
--- config/i386/i386.md	9 Apr 2004 01:34:04 -0000
***************
*** 3677,3683 ****
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
!   "#")

  (define_insn "*truncdfsf2_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
--- 3677,3693 ----
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
! {
!   if (REG_P (operands[1])
!       && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!     return "fstp\t%y0";
!   else if (STACK_TOP_P (operands[0]))
!     return "fld%z1\t%y1";
!   else
!     return "fst\t%y0";
! }
!   [(set_attr "type" "fmov")
!    (set_attr "mode" "SF")])

  (define_insn "*truncdfsf2_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
***************
*** 3920,3926 ****
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
!   "#")

  (define_insn "*truncxfsf2_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
--- 3930,3946 ----
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
! {
!   if (REG_P (operands[1])
!       && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!     return "fstp\t%y0";
!   else if (STACK_TOP_P (operands[0]))
!     return "fld%z1\t%y1";
!   else
!     return "fst\t%y0";
! }
!   [(set_attr "type" "fmov")
!    (set_attr "mode" "SF")])

  (define_insn "*truncxfsf2_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
***************
*** 3999,4005 ****
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
!   "#")

  (define_insn "*truncxfdf2_1"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
--- 4019,4035 ----
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
! {
!   if (REG_P (operands[1])
!       && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!     return "fstp\t%y0";
!   else if (STACK_TOP_P (operands[0]))
!     return "fld%z1\t%y1";
!   else
!     return "fst\t%y0";
! }
!   [(set_attr "type" "fmov")
!    (set_attr "mode" "DF")])

  (define_insn "*truncxfdf2_1"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")


// PR target/14888
// This used to ICE because the truncdfsf2 isn't completely eliminated

// { dg-do compile }
// { dg-options "-O2 -ffast-math" }

class xcomplex
{
public:
  float re, im;

  xcomplex &operator*= (const float &fact)
  { re*=fact; im*=fact; return *this; }
};

void foo (xcomplex &almT, xcomplex &almG)
{
  double gb;
  almT*=gb;
  almG*=gb*42;
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list