This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: A serious -fpic and -fomit-frame-pointer bug in egcs 1.0.3/1.1
- To: law at cygnus dot com
- Subject: Re: A serious -fpic and -fomit-frame-pointer bug in egcs 1.0.3/1.1
- From: hjl at lucon dot org (H.J. Lu)
- Date: Tue, 7 Jul 1998 08:04:16 -0700 (PDT)
- Cc: egcs-bugs at cygnus dot com
>
>
> In message <m0ytChr-000266C@ocean.lucon.org>you write:
> > I can see this bug is INITIAL_ELIMINATION_OFFSET related. But it is
> > hard to tell if the bug is in INITIAL_ELIMINATION_OFFSET itself. ebx
> > is used or not depends not only on PIC, but also optimization and
> > CPU. INITIAL_ELIMINATION_OFFSET is used twice in reload1.c. I can
> > think of 2 possible fixes:
> >
> > 1. Remove one of them.
> > 2. Treat both of them the same.
> It's not a question of having two calls to INITIAL_ELIMINATION_OFFSET,
> the compiler is supposed to work when the two calls produce different
> results. In fact, the second call can be executed many times because
> the offsets may change when something gets spilled to the stack.
>
> If something changes after the big while loop in reload1.c::reload,
> then that's a problem. But I get the feeling your call to
Yes. It does happen. On x86, some FP constants are allowed as an
operand in some pattern. See CONST_DOUBLE_OK_FOR_LETTER_P. The problem
is not all patterns take it. During the reload, a pattern, which allows
a FP constant, is changed and a pattern, which has to take a memory
operand, now has a FP constant as operand. See what find_reloads
in reload.c does in this case:
/* Any constants that aren't allowed and can't be reloaded
into registers are here changed into memory references. */
for (i = 0; i < noperands; i++)
if (! goal_alternative_win[i]
&& CONSTANT_P (recog_operand[i])
/* force_const_mem does not accept HIGH. */
&& GET_CODE (recog_operand[i]) != HIGH
&& ((PREFERRED_RELOAD_CLASS (recog_operand[i],
(enum reg_class) goal_alternative[i])
== NO_REGS)
|| no_input_reloads)
&& operand_mode[i] != VOIDmode)
{
*recog_operand_loc[i] = recog_operand[i]
= find_reloads_toplev (force_const_mem (operand_mode[i],
recog_operand[i]),
i, address_type[i], ind_levels, 0);
if (alternative_allows_memconst (constraints1[i],
goal_alternative_number))
goal_alternative_win[i] = 1;
}
As you can see, force_const_mem is called.
> force_const_mem that is causing the offsets to change is occuring
> after the first call to INITIAL_ELIMINATION_OFFSET, but before the
> second call.
>
I guess it only happens when force_const_mem is called and PIC
is used and we have to call/pop to get PIC reg.
We can make CONST_DOUBLE_OK_FOR_LETTER_P always returns 0. It means the
above call to force_const_mem will be never made on x86. Or we can
update those data stuctures after each INITIAL_ELIMINATION_OFFSET if
force_const_mem is called. If possible, we can put those updates
inside the INITIAL_ELIMINATION_OFFSET macro.
> That should still be OK -- the compiler is supposed to handle that
> situation. If it isn't, we need to dive deeper into the problem.
No, it doesn't.
--
H.J. Lu (hjl@gnu.org)