[PATCH] New *truncsfdf2_i387_1 pattern for i386.md

Roger Sayle roger@eyesopen.com
Mon Apr 4 00:51:00 GMT 2005


The following patch is a proposed improvement to the x86 backend to
improve floating point double to float truncation.  Consider the
following very simple example:

double d;
float f;

void foo()
{
  f = d;
}

with "-O2 -fomit-frame-pointer", mainline currently generates:

foo:    pushl   %edx
        fldl    d
        fstps   (%esp)
        flds    (%esp)
        fstps   f
        popl    %eax
        ret

The issue is that the x87 can only truncate a value to a float with
a write to memory.  Hence for register->register truncations it needs
to allocate a temporary stack slot, write the truncated value there
and then load it back in.  Unfortunately, if the "target" is already
a MEM, this introduces the bizarre overhead above.

With the patch below we now generate:

foo:    pushl   %edx
        fldl    d
        fstps   f
        popl    %eax
        ret

We still (unfortunately) allocate the stack slot, but combine.c is
now able to recognize the result of merging the float_truncate with
the write to memory.  Interestingly, we already have the equivalent
*truncxfsf2_387_1 and *truncxfdf2_387_1 patterns, so its a surprise
that the df->sf pattern is missing, but I suspect this is due to the
labyrinthine interactions between x87 and sse2 math.  To play it safe,
the new pattern is only enabled if we know we can't use sse2, but
that might be overly conservative.  Uros or RTH?


The following patch has been tested on i686-pc-linux-gnu, with a full
"make bootstrap", all default languages including Ada, and regression
tested with a top-level "make -k check" with no new failures.

Ok for mainline?



2005-04-03  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.md (*truncdfsf2_i387_1): New pattern.


Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.622
diff -c -3 -p -r1.622 i386.md
*** config/i386/i386.md	1 Apr 2005 03:42:48 -0000	1.622
--- config/i386/i386.md	3 Apr 2005 20:15:51 -0000
***************
*** 3787,3792 ****
--- 3787,3808 ----
    [(set_attr "type" "fmov,multi")
     (set_attr "mode" "SF")])

+ (define_insn "*truncdfsf2_i387_1"
+   [(set (match_operand:SF 0 "memory_operand" "=m")
+ 	(float_truncate:SF
+ 	  (match_operand:DF 1 "register_operand" "f")))]
+   "TARGET_80387
+    && !(TARGET_SSE2 && TARGET_SSE_MATH)
+    && !TARGET_MIX_SSE_I387"
+ {
+   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+     return "fstp%z0\t%y0";
+   else
+     return "fst%z0\t%y0";
+ }
+   [(set_attr "type" "fmov")
+    (set_attr "mode" "SF")])
+
  (define_split
    [(set (match_operand:SF 0 "register_operand" "")
  	(float_truncate:SF


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