This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/22167] [3.4 regression] Strange optimization bug when using -Os
- From: "rsandifo at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 14 Jul 2005 13:49:01 -0000
- Subject: [Bug rtl-optimization/22167] [3.4 regression] Strange optimization bug when using -Os
- References: <20050623233721.22167.dahowell@directv.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From rsandifo at gcc dot gnu dot org 2005-07-14 13:49 -------
I think this is a bug in gcse.c:hoist_code. It appears to date back
to when the code was first added.
The function is supposed to be doing the following:
for each block BB
for each expr E
HOISTABLE := 0
A: if (E is very busy at the end of BB
&& E is transparent at the end of BB)
for each block BB' that is dominated by BB
if (BB' uses E
&& a computation of E at the end of BB would reach that use)
HOISTABLE := HOISTABLE + 1
HOIST_EXPRS[E] := HOISTABLE > 1
if there exists an E such that HOIST_EXPRS[E] > 0
for each expr E
B: if HOIST_EXPRS[E]
for each block BB' that is dominated by BB
if (BB' uses E
&& a computation of E at the end of BB would reach that use)
replace the use with the reaching reg
Unfortunately, the implementation of condition B is checking the wrong
bitmap (hoist_vbeout instead of hoist_exprs). In other words, the code
is effectively doing:
B: if E is very busy at the end of BB
Thus hoist_code() would do nothing for a function that has no candidate
expressions with two or more suitable uses. However, if a function
_does_ have such an expression, hoist_code() would hoist all candidate
expressions, even if they have only one use. And it would effectively
drop the all-important "E is transparent at the end of BB" condition
when doing this.
So what happens on MIPS (and presumably powerpc) is this: we have two
candidate expressions that are of interest:
1. (mem s.p)
2. (high "p is 0x%x and p2 ...")
Both expressions are very busy on the output from block 0, which ends
with the call to S::init(). And both expressions have more than one
suitable use. However, expression 1 is not entered in HOIST_EXPRS
because it is not transparent at the end of block 0. We'd have to
insert the load _before_ the call to S::init(), and that would change
its value. Expression 2 _is_ transparent at the end of block 0 and
so HOIST_EXPRS[2] is correctly set to true.
So we have one expression that we want to hoist -- expression 2 -- and
we therefore enter the second loop. This then ignores the fact that
expression 1 is not transparent at the end of block 0 and hoists it
anyway.
Although I haven't checked, I think the reason this doesn't show up
on i686 is because there's no equivalent of (high ...) that would
cause the second loop to be executed.
Richard
--
What |Removed |Added
----------------------------------------------------------------------------
AssignedTo|unassigned at gcc dot gnu |rsandifo at gcc dot gnu dot
|dot org |org
Status|NEW |ASSIGNED
Last reconfirmed|2005-06-29 14:40:54 |2005-07-14 13:49:01
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22167