Bug in gcc-20020114: m68k doesn't use tstsf/tstdf patterns

law@redhat.com law@redhat.com
Wed Mar 6 11:30:00 GMT 2002


In message <200201212030.g0LKUBo10347@hyper.wm.sps.mot.com>, Peter Barada write
s:
 > 
 > The following code:
 > 
 > typedef float ftype;
 > int tstf(ftype x0, ftype x1)
 > {
 >   int i,err;
 >   ftype sigma;
 > 
 >   for (err=0, i=0; i<100; ++i) {
 >     sigma = sigma * x0 + x1;
 >     if (sigma < (ftype)0.0)
 >       err = 1;
 >   }
 >   return err;
 > }
 > 
 > 
[ ... ]
 > generates the following output:
 > 
 > tstf:
 > 	link.w %a6,#0
 > 	move.l %d2,-(%sp)
 > 	move.l 8(%a6),%d2
 > 	move.l 12(%a6),%d0
 > 	fmovecr #0xf,%fp0
 > 	sub.l %a0,%a0
 > 	fmove.x %fp0,%fp1
 > 	moveq.l #99,%d1
 > .L5:
 > 	fsglmul.s %d2,%fp0
 > 	fadd.s %d0,%fp0
 > 	fcmp.x %fp1,%fp0     <-- notice fcmp.x instead of ftst.x
 > 	fbnlt .L4
 > 	move.w #1,%a0
 > .L4:
 > 	subq.l #1,%d1
 > 	jbpl .L5
 > 	move.l %a0,%d0
 > 	move.l (%sp)+,%d2
 > 	unlk %a6
 > 	rts
Also notice that the ftst is redundant as we could use condition code
values set by the fadd.s.  That would create a loop which looks like:

.L8:
        fsglmul.s %d0,%fp0
        fadd.x %fp1,%fp0
        fbnlt .L4
        move.w #1,%a0
.L4:
        subq.l #1,%d1
        jbpl .L8

 > To fix this, I changed the COST_DOUBLE clause of CONSTS_COSTS in 
 > gcc/config/m68k/m68k.h to be:
 > 
 >   case CONST_DOUBLE: \
 >     /* Make sure that 0.0 is *really* cheap enough for tstsf/tstdf */ \
 >     if ((RTX) == CONST0_RTX (SFmode) || (RTX) == CONST0_RTX (DFmode)) \
 >       return COSTS_N_INSNS (1); \
 >     else \
 >       return 5;
I did something slightly different.  0.0 is really only cheaper in a
compare insn because we can use a tst insn instead (which we might later
manage to remove).  Thus my change restricts the reduction in cost to
cases where OUTER_CODE is a COMPARE.

Here's the patch I've checked into the development sources (not the GCC 3.1
branch):


-------------- next part --------------
        * m68k.h (CONST_COSTS): Lower cost of 0.0 when used inside a
        COMPARE operator.

Index: m68k.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68k/m68k.h,v
retrieving revision 1.67
diff -c -3 -p -r1.67 m68k.h
*** m68k.h	2002/03/03 21:10:00	1.67
--- m68k.h	2002/03/06 19:23:44
*************** __transfer_from_trampoline ()					\
*** 1555,1560 ****
--- 1555,1566 ----
    case SYMBOL_REF:						\
      return 3;							\
    case CONST_DOUBLE:						\
+     /* Make 0.0 cheaper than other floating constants to	\
+        encourage creating tstsf and tstdf insns.  */		\
+     if ((OUTER_CODE) == COMPARE					\
+         && ((RTX) == CONST0_RTX (SFmode)			\
+ 	    || (RTX) == CONST0_RTX (DFmode)))			\
+       return 4;							\
      return 5;
  
  /* Compute the cost of various arithmetic operations.


More information about the Gcc-patches mailing list