public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Promoting floats to doubles?
@ 2004-05-02  6:32 Kean Johnston
  2004-05-03 20:39 ` Jim Wilson
  0 siblings, 1 reply; 15+ messages in thread
From: Kean Johnston @ 2004-05-02  6:32 UTC (permalink / raw)
  To: GCC development group

Hi,

In going through a G77 testcase failure when I had TARGET_C99_FUNCTIONS 
defined, I came across something that confuses me. The failure shows 
itself whenever a float argument is passed to something like, for 
example, floorf(). The function in libm.so is expecting the float to 
have been promoted to a double and is wanting to pull 8 bytes off the 
stack. But only 4 are being pushed on (fstps (%esp)) instead of the 8 
(%fstpl %(esp)).

Is there a way I can instruct GCC to always promote floats?

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-02  6:32 Promoting floats to doubles? Kean Johnston
@ 2004-05-03 20:39 ` Jim Wilson
  2004-05-04  1:25   ` Kean Johnston
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-03 20:39 UTC (permalink / raw)
  To: Kean Johnston; +Cc: gcc

Kean Johnston wrote:
> Is there a way I can instruct GCC to always promote floats?

In K&R C, floats are promoted to double.  In ISO C, they are not.

The main difference here is prototypes.  If you have an old-style 
function definition, and there is no prototype in scope, then it will be 
compiled with floats promoted to double.  If you have a function call, 
and there is no prototype in scope, or this is an unnamed stdarg 
argument, then a float will be promoted to double.

If there is a prototype, and the prototype specifies float, then the 
float will not be promoted to double.

It sounds like you have a prototype that disagrees with the function 
definition, in which case you should fix the prototype.

There are some hooks here, TARGET_PROMOTE_FUNCTION_ARGS, 
TARGET_PROMOTE_PROTOTYPES, TARGET_PROMOTE_FUNCTION_RETURN, but they are 
really only useful for promoting char/short/int types.  They won't work 
for promoting float to double.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-03 20:39 ` Jim Wilson
@ 2004-05-04  1:25   ` Kean Johnston
  2004-05-04  4:00     ` Jim Wilson
  0 siblings, 1 reply; 15+ messages in thread
From: Kean Johnston @ 2004-05-04  1:25 UTC (permalink / raw)
  To: Jim Wilson; +Cc: gcc

> If there is a prototype, and the prototype specifies float, then the 
> float will not be promoted to double.
> 
> It sounds like you have a prototype that disagrees with the function 
> definition, in which case you should fix the prototype.

It turns out I have a real problem on my hands. The OSR5 ABI
dictates that floats are always promoted to doubles. I know
thats bad and broken, but thats what I have. So even though
the prototypes are correct - for example, the particular
function that was causing the problem with g77 is prototyped
as extern float floorf (float), the OSR5 compiler, which was
used to produce libm, promoted the float arg to a double.

I guess one way around this would be to hack this with fixinc
and have it always change the prototypes from float to double.
I can't see any other way around this. Can you?

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04  1:25   ` Kean Johnston
@ 2004-05-04  4:00     ` Jim Wilson
  2004-05-04 17:45       ` Kean Johnston
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-04  4:00 UTC (permalink / raw)
  To: Kean Johnston; +Cc: gcc

On Mon, 2004-05-03 at 18:15, Kean Johnston wrote:
> It turns out I have a real problem on my hands. The OSR5 ABI
> dictates that floats are always promoted to doubles.

You could look at gcc versions from a few versions ago, find the K&R C
support that did this, and re-add it suitably configured so it can be
enabled for your target only.

You could look at the current PROMOTE_FUNCTION_ARG/PROMOTE_PROTOTYPES
stuff and extend it so that it works for float->double conversions.

You can use fixinc to fix the prototypes.

The fixinc solution has the flaw that code with prototypes that use
float won't be portable between the SCO compiler and GCC.  You can fix
the system header prototypes, but you can't fix the prototypes in all
applications and libraries.

The first two solutions have the flaw that they violate the intent of
ISO C, though I don't think they violate the letter of the standard. 
Converting float to double won't change the value.  It just makes the
code less efficient, as you will have an unnecessary float to double
conversion in the caller, and an unnecessary double to float conversion
in the callee.  Any well written program should not be affected by these
unnecessary conversions.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04  4:00     ` Jim Wilson
@ 2004-05-04 17:45       ` Kean Johnston
  2004-05-04 18:52         ` Joseph S. Myers
  2004-05-04 20:52         ` Jim Wilson
  0 siblings, 2 replies; 15+ messages in thread
From: Kean Johnston @ 2004-05-04 17:45 UTC (permalink / raw)
  To: Jim Wilson; +Cc: gcc

> You could look at the current PROMOTE_FUNCTION_ARG/PROMOTE_PROTOTYPES
> stuff and extend it so that it works for float->double conversions.
I took a look at this, and I think extending it to support
float-doubles will be ... tricky. It may not even be appropriate,
considering that the docs talk about them being specifically for
integrals that are less than the native width.

Now I was able to achive what I needed to by hacking in two functions:
c-typeck.c:default_conversion(), where I added:
  if (TYPE_MAIN_INVARIANT (type) == float_type_node)
    return convert (double_type_node, exp);
and in c-typeck.c:convert_arguments(), where I extended the check
after the call to targetm.calls.promoto_prototypes to check for
a TREE_TYPE(type) == REAL_TYPE.

The first case I think should be protected by something like
#if TARGET_PROMOTES_FLOAT_TO_DOUBLE. My only concern is that I dont
know if thats the right function to put the conversion in, as I dont
know all of the circumstances under which default_conversion() is
called. Perhaps the right thing to do is isolate any changes to
convert_arguments().

For convert_arguments() itself, I think this type of check needs
to happen pretty early on. If the target requires this sort of
promotion to satisfy some ABI brain-damage, and this conversion
will always happen, then there is no point in warning about it.
So, the conversion should happen before the warning checks that
start close to the top of the fn. That implies that type can
change before the call to convert_for_assignment(). I am again
unsure of the consequences of this, so I would appreciate a little
guidance. Alternately, the conversion can happen later and the
warnings about float to fouble promotion can be silenced by
something like #ifndef TARGET_ALWAYS_PROMOTES_FLOATS. If this is
acceptable, then I can perhaps extend the code after the check
for targetm.calls.promote_prototypes(), which will always fail
becuase a float wont pass the INTEGRAL_TYPE_P() check. Thus I
could extend the if (targetm.calls...) at the end to say:
#ifdef TARGET_ALWAYS_PROMOTES_FLOATS
   else if (TREE_CODE (type) = REAL_TYPE)
     parmval = convert (double_type_node, parmval);
#endif

> The fixinc solution has the flaw that code with prototypes that use
> float won't be portable between the SCO compiler and GCC.  You can fix
> the system header prototypes, but you can't fix the prototypes in all
> applications and libraries.
True. I've abandoned the fixinc notion (after having come up with
a suitably gnarly sed script to do the conversion of course :P)

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04 17:45       ` Kean Johnston
@ 2004-05-04 18:52         ` Joseph S. Myers
  2004-05-04 20:44           ` Jim Wilson
  2004-05-04 20:52         ` Jim Wilson
  1 sibling, 1 reply; 15+ messages in thread
From: Joseph S. Myers @ 2004-05-04 18:52 UTC (permalink / raw)
  To: Kean Johnston; +Cc: Jim Wilson, gcc

On Tue, 4 May 2004, Kean Johnston wrote:

> and in c-typeck.c:convert_arguments(), where I extended the check
> after the call to targetm.calls.promoto_prototypes to check for
> a TREE_TYPE(type) == REAL_TYPE.

It's a defect in the back-end interface that the front end has a call to
such a target hook at all.  This should actually be handled somewhere in
the middle-end generating code for function calls, which should take calls
with their original types and handle promotion as required by the ABI;  
such promotion has no semantic effect so each front end shouldn't need to
deal with it.

If this ABI requirement needs a new target hook, it would be better to
have one that only needs to be called once in the compiler rather than in
every front end.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04 18:52         ` Joseph S. Myers
@ 2004-05-04 20:44           ` Jim Wilson
  2004-05-05  0:06             ` Kean Johnston
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-04 20:44 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Kean Johnston, gcc

On Tue, 2004-05-04 at 11:52, Joseph S. Myers wrote:
> It's a defect in the back-end interface that the front end has a call to
> such a target hook at all.

I think this is more likely a C compiler issue than an ABI issue.  If
only the C compiler promotes float to double, then the conversion has to
happen in the C front end.  This is the case with the old K&R C
requirement of promoting floats to doubles, which was implemented in the
C front end.

It would be good to check this though.  If the SCO compiler supports
Fortran, Java, Ada, or C++, check to see if any of the other languages
need this conversion.  My expectation is that they do not.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04 17:45       ` Kean Johnston
  2004-05-04 18:52         ` Joseph S. Myers
@ 2004-05-04 20:52         ` Jim Wilson
  2004-05-05  0:14           ` Kean Johnston
  1 sibling, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-04 20:52 UTC (permalink / raw)
  To: Kean Johnston; +Cc: gcc

On Tue, 2004-05-04 at 10:35, Kean Johnston wrote:
> The first case I think should be protected by something like
> #if TARGET_PROMOTES_FLOAT_TO_DOUBLE. My only concern is that I dont
> know if thats the right function to put the conversion in, as I dont
> know all of the circumstances under which default_conversion() is
> called. Perhaps the right thing to do is isolate any changes to
> convert_arguments().

This is why I suggested looking at the old K&R C support, which is
presumably exactly what you need to be compatible with the SCO compiler.

So look at gcc-2.8.1, grep for flag_traditional... I see code in
default_conversion for arguments.  store_parm_decls and
combine_parm_decls for parameters.  And grokdeclarator for return
values.  The last one is optional, since not all K&R C compilers
promoted return values.  So the default_conversion change seems right. 
The store_parm_decls/combine_parm_decls stuff has changed a bit since
2.8.1, so you might have to look at that a bit closer.

> #ifdef TARGET_ALWAYS_PROMOTES_FLOATS
>    else if (TREE_CODE (type) = REAL_TYPE)
>      parmval = convert (double_type_node, parmval);
> #endif

If this is a C front-end specific hook, then putting "always" in the
name is a bit misleading.  Maybe something like
TARGET_KANDRC_PROMOTE_FLOATS.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04 20:44           ` Jim Wilson
@ 2004-05-05  0:06             ` Kean Johnston
  2004-05-05  2:18               ` Jim Wilson
  2004-05-05  7:10               ` Jim Wilson
  0 siblings, 2 replies; 15+ messages in thread
From: Kean Johnston @ 2004-05-05  0:06 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Joseph S. Myers, gcc

> It would be good to check this though.  If the SCO compiler supports
> Fortran, Java, Ada, or C++, check to see if any of the other languages
> need this conversion.  My expectation is that they do not.
Well the native compilers just support C and C++, and C++ is
just the god-aweful cfront stuff, so its all C under the hood anyway.
But thats a bit of a moot point, as even a Java or C++ or Fortran
program can (and most liekly will) link against things like libm.so,
which was compiled by the SCO compiler, and which requires these
convesions, so the point Joseph makes is valid, it shouldn't be language
specific.

I confess great ignorance to the workings of GCC. I only ever got to
know enough about it to do the SCO port and I know almost enough to
maintain it, with a little help from you guys :) If you or Joseph could
point me in the right direction for doing this at the appropriate level
(I believe the term Joseph used was the "middle-end" or "backend" then
I can chase it down with hopefully a minimal amount of nagging.

Thank you both for your help so far though, its been great.

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-04 20:52         ` Jim Wilson
@ 2004-05-05  0:14           ` Kean Johnston
  0 siblings, 0 replies; 15+ messages in thread
From: Kean Johnston @ 2004-05-05  0:14 UTC (permalink / raw)
  To: Jim Wilson; +Cc: gcc

> So look at gcc-2.8.1, grep for flag_traditional... I see code in
> default_conversion for arguments.  store_parm_decls and
> combine_parm_decls for parameters.  And grokdeclarator for return
> values.  The last one is optional, since not all K&R C compilers
> promoted return values.  So the default_conversion change seems right. 
> The store_parm_decls/combine_parm_decls stuff has changed a bit since
> 2.8.1, so you might have to look at that a bit closer.

Thank you I will go look at those. As I said in my previous mail
I think the problem is broader than C, as no matter what language
you use its probably going to end up using libm if you do any math
stuff, so in effect it really is an ABI issue. I'm working my way
through the GCC docs to try to get a better understanding of where
the appropriate place may be to do this.

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-05  0:06             ` Kean Johnston
@ 2004-05-05  2:18               ` Jim Wilson
  2004-05-05  7:10               ` Jim Wilson
  1 sibling, 0 replies; 15+ messages in thread
From: Jim Wilson @ 2004-05-05  2:18 UTC (permalink / raw)
  To: Kean Johnston; +Cc: Joseph S. Myers, gcc

On Tue, 2004-05-04 at 16:57, Kean Johnston wrote:
> But thats a bit of a moot point, as even a Java or C++ or Fortran
> program can (and most liekly will) link against things like libm.so,
> which was compiled by the SCO compiler

But the only reason that libm is a problem is because the prototypes in
the system header files are wrong, and these prototypes won't work with
Fortran code, so you don't need the promotion for Fortran.  The system
header files also won't work for Ada, Pascal, etc.  I don't know if
system header file prototypes matter for Java, does Java code ever
include <math.h>?  If no, then you don't need the promotion for Java. We
can also ask the question of whether the prototypes get used for C++
code, but it probably does.  This makes it a C family issue again.

I think it is a judgment call as to whether you need to fix this with an
ABI change or a C/C++ family front end change.  I am inclined to treat
it as a C family problem, because the underlying problem is that SCO
still has a compiler following K&R C rules instead of ISO C rules.  But
it is reasonable to also handle this as an ABI issue.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-05  0:06             ` Kean Johnston
  2004-05-05  2:18               ` Jim Wilson
@ 2004-05-05  7:10               ` Jim Wilson
  2004-05-05  9:10                 ` Kean Johnston
  1 sibling, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-05  7:10 UTC (permalink / raw)
  To: Kean Johnston; +Cc: Joseph S. Myers, gcc

Kean Johnston wrote:
> program can (and most liekly will) link against things like libm.so,
> which was compiled by the SCO compiler, and which requires these
> convesions, so the point Joseph makes is valid, it shouldn't be language
> specific.

Thinking about this some more, I am starting to think that Joseph is 
right.  floorf is a C99 function, so we can't change its prototype, thus 
we need an ABI change rather than a C front end change.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-05  7:10               ` Jim Wilson
@ 2004-05-05  9:10                 ` Kean Johnston
  2004-05-05 22:47                   ` Jim Wilson
  0 siblings, 1 reply; 15+ messages in thread
From: Kean Johnston @ 2004-05-05  9:10 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Joseph S. Myers, gcc

> Thinking about this some more, I am starting to think that Joseph is 
> right.  floorf is a C99 function, so we can't change its prototype, thus 
> we need an ABI change rather than a C front end change.
Yup, thats where I am at.

I'm having a spot of bother trying to figure out where to do it
though. I changed PROMOTE_MODE to be:
#define PROMOTE_MODE(MODE,UNSIGNEDP, TYPE) \
do { \
  if (((MODE) == HImode && TARGET_PROMOTE_HI_REGS) \
      || (MODE) == QImode && TARGET_PROMOTE_QI_REGS)) \
    (MODE) = SImode; \
  else if (((MODE) == SFmode)) \
    (MODE) = DFmode; \
} while (0)

and added:
#define PROMOTE_FUNCTION_ARGS
#define PROMOTE_FOR_CALL_ONLY

Unfortunately when I compile things this way I get an ICE in
expand_call, at calls.c:3131. Clearly then, this isnt the right
place. I've read quite a bit of gdbint.info and I cant find what
may be the right place to do this sort of thing. I just dont know
the internals well enough so I will pause for advice from you
or Joseph.

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-05  9:10                 ` Kean Johnston
@ 2004-05-05 22:47                   ` Jim Wilson
  2004-05-05 23:48                     ` Kean Johnston
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Wilson @ 2004-05-05 22:47 UTC (permalink / raw)
  To: Kean Johnston; +Cc: Joseph S. Myers, gcc

On Wed, 2004-05-05 at 02:00, Kean Johnston wrote:
> #define PROMOTE_MODE(MODE,UNSIGNEDP, TYPE) \
> #define PROMOTE_FUNCTION_ARGS
> #define PROMOTE_FOR_CALL_ONLY

PROMOTE_FOR_CALL_ONLY was removed last week by the way.

The PROMOTE_MODE stuff may not work in your case.  Currently, they are
only for integers (char/short/int/long), and they work by adding
SUBREGs.  However, SUBREGs can not be used for converting floats to
doubles and vice versa.  So the PROMOTE_MODE stuff will just lead to
trouble.  You might be able to get it working, but you will have to
rewrite the code a bit.  It might be easier to add some new hooks which
are used in the same places but generate conversions instead of adding
subregs.

It is probably easier to do this in the C front end, even if that is the
wrong place to do this.  It will be a bit more work to do this in the
middle-end.  I don't believe there are any existing hooks for this.  I
will you will. have to write some code to get this working in the
middle-end.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Promoting floats to doubles?
  2004-05-05 22:47                   ` Jim Wilson
@ 2004-05-05 23:48                     ` Kean Johnston
  0 siblings, 0 replies; 15+ messages in thread
From: Kean Johnston @ 2004-05-05 23:48 UTC (permalink / raw)
  To: Jim Wilson; +Cc: Joseph S. Myers, gcc

> It is probably easier to do this in the C front end, even if that is the
> wrong place to do this.  It will be a bit more work to do this in the
> middle-end.  I don't believe there are any existing hooks for this.  I
> will you will. have to write some code to get this working in the
> middle-end.

I think you're right. I dont know anywhere near enough to make any
kind of sensible changes to the middle end, but I can grok the front
end stuff OK. I already have it working for C, and I will look at
doing it for C++ next. Those are my two big concerns. If I end up
having to do this in all of the frontends (well, its just Fortran
and Java after that for this platform) then so be it. Over time
perhaps I can be educated into how to do this more "correctly" in
the middle end. Joseph seemed to have a good grasp on that so
perhaps when he has time we can talk about doing it better.

At this stage I'd rather change the front-ends and get the stuff
working than wait to engineer a middle or backend solution. I
dont mind ripping the front-end code out once (or if) we reach a
better solution in the backend.

Kean

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2004-05-05 23:48 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-02  6:32 Promoting floats to doubles? Kean Johnston
2004-05-03 20:39 ` Jim Wilson
2004-05-04  1:25   ` Kean Johnston
2004-05-04  4:00     ` Jim Wilson
2004-05-04 17:45       ` Kean Johnston
2004-05-04 18:52         ` Joseph S. Myers
2004-05-04 20:44           ` Jim Wilson
2004-05-05  0:06             ` Kean Johnston
2004-05-05  2:18               ` Jim Wilson
2004-05-05  7:10               ` Jim Wilson
2004-05-05  9:10                 ` Kean Johnston
2004-05-05 22:47                   ` Jim Wilson
2004-05-05 23:48                     ` Kean Johnston
2004-05-04 20:52         ` Jim Wilson
2004-05-05  0:14           ` Kean Johnston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).