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