egcs-1.1b alpha-dec-osf3.2 internal error in change_address()

Hans-Peter Nilsson hp@bitrange.com
Tue Apr 6 13:48:00 GMT 1999


On Tue, 6 Apr 1999, Fergus Henderson wrote:
> On 04-Apr-1999, Hans-Peter Nilsson <hp@bitrange.com> wrote:
> > (This still happens in current CVS.)
> > 
> > Regarding your report in
> > <URL: http://egcs.cygnus.com/ml/egcs-bugs/1999-03/msg00945.html >.
> > > register        Word    mr6 __asm__("$15");      
> > This is the frame-pointer-register (i.e. internally used by gcc)
> > and it is incorrect to use it this way in a program.
> 
> Well, OK, I suppose that would be fair enough.  That is news to me,
> however.  The GNU C manual does not document that you're not allowed to
> use the frame pointer register for a global register variable, and on
> the Alpha we have been successfully using it with various different
> versions of gcc since 1996/04/30.  We've tested it with about 200,000
> lines of Mercury code that gets compiled to millions of lines of
> automatically generated C code, and this is the first time we've had a
> problem with that.  Indeed, we started using the frame pointer as
> a register variable long enough ago now that I had forgotten about it.

I understand your concerns about existing code "breaking", but this
should be expected for questionable constructs with newer compiler
versions.  Sorry.

A suggested solution in practice is to fix your code, or not use
gcc-versions of which you have not (thoroughly and repeatedly with
every code edit - hardly practical) checked the generated assembly
output.

> I guess we've always understood that using the frame pointer was a bit
> questionable, but it did work,

Your code relies on passing specific optimization switches
(e.g. specifying or implying -fomit-frame-pointer) to gcc for correct
behavior.  This is by many wise people (including yourself it seems,
at least to some extent) considered a questionable construct, no
matter how good it works for a specific gcc version.

In your bug-report, you do not state any optimization options at all,
specifically none implying -fomit-frame-pointer, so gcc would use a
frame-pointer and the breakage is inevitable.

It would be purely by accident, if code such as this worked unless
-fomit-frame-pointer was specified or inferred to gcc.

> so if the intent is to disallow this
> then I think it would be a good idea to explicitly state this in the
> gcc manual.

Agreed.  I submitted a patch yesterday to this effect for the manual
and gcc for global and local register variables
<URL: http://egcs.cygnus.com/ml/egcs-patches/1999-04/msg00124.html >
(no rocket science, just copied what the -fcall-used-X etc. does).

> But are you sure this is the intent?  Note that the documentation for
> global register variables suggests that declaring a global register
> variable is similar to using `-ffixed-REG', not `-fcall-used-REG'.

No, it does not say so, and quite I'm sure of the intent.  What it
says about -ffixed-REG in this context is currently (extend.texi):

  If you want to recompile @code{qsort} or other source files which do not
  actually use your global register variable, so that they will not use that
  register for any other purpose, then it suffices to specify the compiler
  option @samp{-ffixed-@var{reg}}.  You need not actually add a global
  register declaration to their source code.

This is advice of how to use code with register variables together
with *other* code; other code that would otherwise use that register
for its own purposes.

> The documentation for `-fcall-saved-REG' and `-fcall-used-REG'
> explicitly warns against using those options for the frame pointer,
> but in contrast the documentation for `-ffixed-REG' specifically
> allows it:
> 
>  | `-ffixed-REG'
>  |      Treat the register named REG as a fixed register; generated code
>  |      should never refer to it (except perhaps as a stack pointer, frame
>  |      pointer or in some other fixed role).

No, this allows *gcc* to refer to it in the code it generates.
Compiler input (source) is seldom referred to as "generated code" in
this context, so I don't really see the confusion, although there may
be a better wording.

> I guess my understanding of using the frame pointer or stack pointer as a
> global register variable was that this usage was questionable, but allowed.

Questionable but *overlooked*, IMHO.

> That is, I thought it was up to the user to ensure that their use of it
> did not conflict with gcc's use of it -- for example, by compiling with
> `-fomit-frame-pointer' and by writing their C code carefully to ensure
> that gcc can always omit the frame pointer, or by only ever reading
> the variable, never writing it, or by some other method.  And if the
> usage did conflict, then I would expect no error at compile time
> (a warning would be nice, of course, but would not be expected),
> instead I would just expect nasty things to happen at runtime.

Very few people would "expect nasty things" at runtime because of
register allocation issues in the compiler (not counting compiler
folks :-)  Using -fomit-frame-pointer is no *guarantee* that gcc can
alway omit a frame-pointer from generated code.

> Is this too much to expect?

Expecting gcc to behave the same about constructs that you yourself
agree are questionable is IMHO expecting too much (as has also been
stated in similar contexts elsewhere, by others too).

What should be expected from a given port of gcc is to be stable as a
rock with every possible -fcall-used-REG or asm-reg you give it; it
should work the same way all the way *or* give a compile-time error,
regardless of other switches.  If it does not, it should be fixed in
that direction.
 But I guess the limit where a compile-time error is generated will
nevertheless vary from version to version, hopefully as an
improvement.

> > I would agree that this failure mode is not good.  Some sanity check
> > along what would happen for '-fcall-used-$15' is better, (although
> > currently the ICE still happens since gcc does not stop at that first
> > error).
> 
> Is this a new error?  I don't observe any message at all with egcs-1.2.

(I assume you mean egcs-1.1.2, since the current CVS, soon-to-be
egcs-1.2 *does* emit an error for this.)

Yes, this is new.  It was introduced to help users that accidentally
used a frame- or stack-pointer this way from getting "nasty" errors.

> > Would that make sense, or is there some reason not to have that check
> > there too (other than "not thought about before or code not submitted")?
> 
> I would much prefer it if this was a warning, rather than an error.
> Particularly for global register variables (we don't really care so much about
> the `-f{fixed,call-used,call-saved}-REG' options, since we don't use them).

But gcc needs the frame-pointer register in the general case, so it
would be incorrect to just warn about it not being available to gcc.

Making the change you seem to propose; to make it work as it used to
and only warn, seems unwise.  Then a seemingly unrelated edit to the
code would cause a compile-time error or "nasty thing at runtime".

> We've got quite a bit of existing, shipped code which uses $15 on Alphas
> and it would be quite unfortunate if the next release of egcs were to
> break that code.

Sorry, your code was already broken.  (Many shipped codes are broken,
but it may be that your code is only broken at the source.  Lucky you,
you can fix it without end-user exposure, or you just have to refrain
from using later versions of gcc.  :-)

brgds, H-P



More information about the Gcc-bugs mailing list