This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFA:] Fix gcc.c-torture/execute/20020720-1.x and further analysis
- From: Roger Sayle <roger at eyesopen dot com>
- To: John David Anglin <dave at hiauly1 dot hia dot nrc dot ca>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 1 Sep 2002 20:54:09 -0600 (MDT)
- Subject: Re: [RFA:] Fix gcc.c-torture/execute/20020720-1.x and further analysis
Hi Dave,
I've now spent several interesting hours in a debugger running
on hppa2.0w-hp-hpux11.00 trying to track the cause of the -O3
failures.
> (insn 16 15 27 0 800003ffeffbb960 (set (reg/v:DF 69)
> (mem/u/f:DF (reg/f:DI 70) [2 S8 A64])) 110 {*pa.md:3107} (insn_list 15 (nil))
> (expr_list:REG_DEAD (reg/f:DI 70)
> (expr_list:REG_EQUAL (const_double:DF 0 [0x0] 0 [0x0] -9223301672405565440 [0x80003fff00000000])
> (nil))))
>
> (insn 27 16 28 0 800003ffeffbb9c0 (set (reg:CCFP 0 %r0)
> (lt:CCFP (reg/v:DF 69)
> (const_double:DF 0 [0x0] 0 [0x0] 0 [0x0]))) 1 {*pa.md:621} (insn_list 16 (nil))
> (expr_list:REG_DEAD (reg/v:DF 69)
> (expr_list:REG_EQUAL (const_int 0 [0x0])
> (nil))))
>
> (jump_insn 28 27 54 0 800003ffeffbb9c0 (set (pc)
> (if_then_else (ne (reg:CCFP 0 %r0)
> (const_int 0 [0x0]))
> (label_ref 31)
> (pc))) 66 {*pa.md:2159} (insn_list 27 (nil))
> (expr_list:REG_DEAD (reg:CCFP 0 %r0)
> (expr_list:REG_BR_PROB (const_int 3000 [0xbb8])
> (nil))))
Although this sequence of three instructions contains enough
information to optimize away the conditional branch, combine
doesn't look at REG_EQUAL notes! This means that its lost
track that (reg:DF 69) has the value 1.0, or even that the
condition codes in (reg:CCFP 0) are always false.
One possible fix, would be to iterate over REG_EQUAL notes
in try_combine, but I fear that would significantly slow
the compiler.
The other possibility is to avoid having (reg:DF 69) placed
in memory at all. This is a constant value provided as a
floating point argument to a function that gets inlined.
If this parameter could be provided to the inlined routine
in a register, or via a constant pool, combine could do the
right thing.
I'm guessing this is why this test doesn't fail at -O3 on
other platforms, that its specific to the PA-RISC ABI that
floating point parameters are always be passed in memory
(even when the function is being inlined?).
Its certainly a strange interaction, that causes inlining
a function to produce worse code! Knowing nothing about
the input, the fabs is preserved, and the fabs(x) < 0.0
optimization triggers. Inlined, such that x is 1.0 (but
in memory) tha fabs(x) is dropped, but combine can't
figure out that 1.0 < 0.0 is always false [unless the
1.0 is an immediate constant or loaded from a constant
pool].
I hope this explains some of the strange behaviour.
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