This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Repost: Gcc-3.0 bug affects spec2000 benchmarks
- To: gcc at gcc dot gnu dot org
- Subject: Repost: Gcc-3.0 bug affects spec2000 benchmarks
- From: Edmar Wienskoski <edmar at motorola dot com>
- Date: Wed, 20 Jun 2001 10:51:08 -0500
- Organization: Motorola
- References: <3B2FB50D.9960DDB2@motorola.com>
Some people couldn't read the original message, so I am reposting it.
--------------------------------------------------------
The following program when compiled with gcc-3.0 on a powerpc system
generates wrong code.
This bug causes spec2000 253.perlbmk benchmark to loop forever.
Regards
Edmar W. Jr.
Program:
=======
double x;
double
foo (void)
{
double value;
value = x;
if (value == 0.0)
value = 1.0;
return value;
}
Compiled with:
=============
gcc -O2 -mcpu=750 -S foo.c
Generates the assembler:
=======================
.file "foo.c"
.section ".rodata"
.align 3
.LC0:
.long 0x0
.long 0x0
.align 3
.LC1:
.long 0x3ff00000
.long 0x0
.section ".text"
.align 2
.globl foo
.type foo,@function
foo:
lis 9,.LC0@ha
la 9,.LC0@l(9)
lfd 0,0(9)
lis 9,x@ha
lfd 1,x@l(9)
lis 9,.LC1@ha
la 9,.LC1@l(9)
fsub 0,1,0
lfd 13,0(9)
fsel 1,0,13,1
blr
.Lfe1:
.size foo,.Lfe1-foo
.comm x,8,8
.ident "GCC: (GNU) 3.0"
Description:
===========
The bug is in the following segment of rs6000.md file.
This segments repeats on movsfcc and movdfcc.
if (GET_MODE (rs6000_compare_op0) == DFmode)
{
temp = gen_reg_rtx (DFmode);
emit_insn (gen_subdf3 (temp, op0, op1));
emit_insn (gen_fseldfsf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negdf2 (temp, temp));
emit_insn (gen_fseldfsf4 (operands[0], temp, operands[0], operands[3]));
}
}
else
{
temp = gen_reg_rtx (SFmode);
emit_insn (gen_subsf3 (temp, op0, op1));
emit_insn (gen_fselsfsf4 (operands[0], temp, operands[2], operands[3]));
if (code == EQ)
{
emit_insn (gen_negsf2 (temp, temp));
emit_insn (gen_fselsfsf4 (operands[0], temp, operands[0], operands[3]));
}
}
The problem is that for this particular program (foo function above),
the function movdfcc is invoked with operand[3] aliased to
operand[0]. In this case the code is expanded to
...
fsel op[0], temp, op[2], op[0]
fneg temp, temp
fsel op[0], temp, op[0], op[0]
...
The optimizer recognizes that the last instruction is useless, and deletes it,
then the fneg is dead and is deleted as well.
On foo.s above we see only the first fsel.
Possible fix:
============
Create a new temporary that copies the value of operand[3], and them use it
in the second fsel.
If operands are not aliased, the copy should be coalesced away, with no
loss in poerformance.
If operands are aliased, the copy should be coalesced on different register,
with no loss in performance.
--
/*----------------------------------------------------------------------*/
/* Edmar Wienskoski Jr. Motorola Inc TX32 MD:PL30 */
/* (512)996-4935 fax:(512)996-7439 7700 W Parmer Lane, Bldg C */
/* edmar@motorola.com Austin, Texas 78729 */
/*----------------------------------------------------------------------*/
____
| [] | ______()_||_
---+----+--- ------------ ------------ ------------ | [] |
| | | | | | | | | | ___| |
|_|______|_| |__________| |__________| |__________| |______________\
"o-o o-o""o-o o-o""o-o o-o""o-o o-o""o-o O-O-O o-o "