This is the mail archive of the gcc@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: sparc vs lapack



  In message <19990714015112.13302.qmail@deer>you write:
  > Sounds to me like not changing this for 32-bit targets is, in itself,
  > the safest approach.
Yup.  This is primarily based on three observations.

  1. If the existing ABI of -femulate-complex was to treat the complex
     value as a struct with two FP values, a complex value can never be
     passed in FP regs (given structure passing conventions in existing
     known ABIs).  This avoids the worries about what to do with complex
     values on 32bit targets which have 64bit wide FP regs.

     i1. We still need to investigate how other compilers handle this, but I
     suspect we'll find their ABIs also treat complex values as aggregates
     rather than two independent FP values.

     i2. We also need to look over each backend that passes args in regs to
     see that it does something sensible for a complex mode argument.

  2. The 32bit targets I've been testing (including ones with 64bit wide
     regs) are not showing any problems with complex values using the
     lapack tests.

  3. And thinking back on the gcc regression tests, it has typically only been
     64bit targets that have shown problems with the tests which use the
     __complex__ extension in C.


  > However, it's important that any test used to determine the initial
  > setting of the ffe_is_emulate_complex_ flag (in gcc/f/top.c) be done
  > early enough to precede any uses of that flag by g77 code.  What
  > comes to mind offhand is the code in ffecom_init_0 (in gcc/f/com.c),
  > but there might be other, earlier, instances.
Thanks for the heads up.

  > So, if the test is simply a preprocessor-time expression that evaluates
  > to a constant, there should be no problem.  (I don't have confidence
  > in myself trying to write such a test, but presume others do.)
MAX_BITS_PER_WORD or something similar :-0


  > Another possibility to consider is to, if feasible, implement a fix
  > assuming the ABI issues are as I stated (__complex__ passed exactly
  > as struct { float; float; };, etc.).  That would at least get things
  > working (probably as well as, or better than, they ever have, for
  > most g77/gcc code that uses complex arithmetic).
Yes.  The biggest concern in this area is the need to verify that the
backends which pass args in registers DTRT for complex values.  Many
key their actions on modes and may not explicitly handle the complex modes.

The MIPS & PA backends are OK for this issue.  I have not looked at any
others.


  > I'm assuming, here, that we know of a fix that will get things basically
  > *working*, just that we aren't sure if it does the right thing vis-a-vis
  > various systems' ABIs.
We don't know of a fix at the moment.  But since it looks like we're starting
to converge on a course of action it seems prudent to start looking for
that solution.

  > I'm also *guessing* that we'll discover no ABI (or perhaps none of much
  > importance) that mandates different treatment of complex than of two
  > floats in a struct.
That is my gut feeling too.


  > or two after the release.  (I haven't really thought through how to ask
  > why these ABI issues aren't already clearly spelled out vis-a-vis gcc's
  > support for __complex__ -- they'd *have* to be, eh?
The usual reason, nobody thought through this particular issue, or if they
did, they didn't leave any clues about their thoughts in the documentation
or sources.

  > But, mostly, I'm *guessing* that, even if we discover such ABI's, users
  > of those systems would *prefer* we shipped with a g77 that defaulted
  > to -fno-emulate-complex, that worked (with the fix), that thereby gave
  > them the better performance, and not care that the results won't be
  > link-time compatible with some other software -- which might not even
  > exist!
If the vendor compilers have an ABI for passing complex values, we should
follow it, even if it means lower performance.  Doing anything else is just
dumb and repeats a mistake that we've already made once (structure return
conventions).  I don't mind making mistakes, but I hate repeating them!

I don't know if you remember all the pain folks had with gcc's "faster, but
incompatible" structure return conventions -- it took years of bug reports
and screaming from users & developers to get gcc to change its default to
be compatible with vendor compilers.


  > Note that, within in the Fortran world, this issue almost certainly
  > affects *only* procedure return values, *not* arguments, because of
  > the pass-by-reference implementation g77 uses.  g77 offers a pass-by-
  > value mechanism -- "CALL FOO(%VAL(C))" -- but no complementary
  > dummy-arg-passed-by-value mechanism.  It's usually the case people
  > want pass-by-value to talk to code written in C or some such thing.
I'd been wondering about this myself.  But the voice in my head had not
gotten loud enough for me to notice it yet.

It certainly matters a lot less for args when the pass by reference stuff
is considered.  In fact, the pass by value nature of fortran strongly argues
for an ABI in which complex values are an aggregate rather than two
independent values.  Otherwise you have to pass a reference to both of
the independent values -- which is still possible, but unlikely IMHO.

In fact, if you consider return values, they strongly suggest an aggregate for
complex values too -- many systems can not handle functions which return
multiple values (as would be the case if we considered complex values as two
independent values).

  > Moreover -- and HEY, THIS MIGHT BE IMPORTANT, WISH I'D THOUGHT OF THIS
  > EARLIER!! -- g77 doesn't normally implement even complex *return values*
  > for COMPLEX functions.  The exceptions I can think of are:
  > 
  >   -  When users compile with -fno-f2c (which discards f2c compatibility)
  > 
  >   -  When compiling *statement* (what gcc calls "nested") COMPLEX functions
Interesting.

  > I wonder, then, how we discovered this problem, if not when compiling
  > a statement function? 
Is this an example of a statement function?  I'm not up enough on Fortran
to know, but it looks suspicious.

      program labug3
      implicit none
      complex one, z
      real    a, f1
      f1(z) = real(z)
      one = (1.,0.)
      a = f1(one) 
      if ( abs(a-1.0) .gt. 1.0e-5 ) then
         write(6,*) 'A should be 1.0 but it is',a
         call abort()
      end if
      end




Is "f1" a statement function in this context?


  > For a statement function, *anything* that gets
  > the code working between the caller (the outer procedure) and the callee
  > will be *fine* -- i.e. *not* an ABI issue (though maybe some debugger
  > support might be an issue, let's remember g77/gdb don't cope with this
  > stuff well anyway).
Depends.  How does a statement function look in RTL?  Is it a CALL or is
it inline expanded into its component operations?


  > Still, the reason I think this path should be considered is that I think
  > that the risk that changing the default back, even though small, and
  > (hopefully) smaller yet if we limit it to 64-bit targets, introduces a
  > *much* greater risk that we start silently generating incorrect code.
It's starting to look that way.

  > OTOH, if we aren't confident that someone like Jim Wilson can come up
  > with a patch that won't expose any new bugs in code that *doesn't*
  > use complex at all, we can't apply it this late in the game, so we
  > should either make sure ICEs happen (for as narrow a range of possible
  > codes as we can feel safe about) or change the default and cross
  > our fingers that *other* latent code-gen bugs won't be exposed.
We haven't done enough investigation yet.  Before burning a lot of time on
"how do I make this test work" I wanted to make sure the direction we were
taking makes sense (ie, I don't want to waste time on a fix which we're just
going to throw away because we realized the basic idea behind the code was
fundamentally braindamaged).

  > In *that* case, the question I'd want answered is whether we could be
  > sure (or make it the case) that the user will get an ICE, rather than
  > bad code, only when the problematic kind of code is compiled.
We can catch this specific instance in the rtl expansion code.  But I have
no confidence that we can catch it in the general sense.

If it is only statement functions that can trip the problem, the maybe we
could catch it in the fortran front-end (conditional of course on 64bit or
wider targets since it looks like they're the only ones effected).


jeff


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