This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: A serious -fpic and -fomit-frame-pointer bug in egcs 1.0.3/1.1


> 
> 
>   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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]