This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

Re: Un-promoting incoming arguments passed by reference


On Mar 23, 2001, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar 22, 2001, Neil Booth <neil@daikokuya.demon.co.uk> wrote:
>> Alexandre Oliva wrote:-
>>> When an argument is promoted and passed by reference, GCC fails to
>>> un-promote the incoming argument.  This patch fixes this bug.  Tested
>>> with a new port, yet to be contributed.  Ok to install?

>> Is there no testcase?

> There is one that's part of the GDB testsuite.  But it would only fail
> with an ABI in which a float argument is promoted to double and then
> passed by transparent reference (i.e., not as in C++'s `float&'), and
> the argument is then used as an argument to a libcall.  For example:

> double f(x, y)
>   float x;
>   double y;
> {
>   return x + y;
> }

> assuming adddf isn't available.

Ok, this no longer fails with mainline, but I still think the DECL of
`x' has something wrong that this patch fixes.  Namely, the type of
the argument as mode SFmode, whereas its RTL has mode DFmode.

Somehow, users of the RTL convert it to the appropriate type, but I
think it would be much saner to set the RTL such that its mode matches
that of the DECL's type, no?

An interesting thing to note is that, with -m5-compact-nofpu, we
currently get no sf2df and df2sf conversions when compiling with -O0,
but we get such conversions when compiling with -O1 and above.
This actually exposes two problems: (i) -O0 is optimizing something
that shouldn't be optimized at -O0, and (ii) -O1 fails to optimize
something that presumably should be optimized.  I haven't investigated
why yet.

Anyway, here's the patch that fixes problem (i) and gets rtxs with the
right mode into such DECL's RTLs.  Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* function.c (assign_parms): De-mote promoted argument passed by
	transparent reference.

Index: gcc/function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.345
diff -u -p -r1.345 function.c
--- gcc/function.c 2002/01/23 12:39:16 1.345
+++ gcc/function.c 2002/02/11 13:52:54
@@ -4749,13 +4749,15 @@ assign_parms (fndecl)
 	  /* If we were passed a pointer but the actual value
 	     can safely live in a register, put it in one.  */
 	  if (passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
-	      && ! ((! optimize
-		     && ! DECL_REGISTER (parm))
-		    || TREE_SIDE_EFFECTS (parm)
-		    /* If -ffloat-store specified, don't put explicit
-		       float variables into registers.  */
-		    || (flag_float_store
-			&& TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)))
+	      /* If by-reference argument was promoted, de-mote it.  */
+	      && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
+		  || ! ((! optimize
+			 && ! DECL_REGISTER (parm))
+			|| TREE_SIDE_EFFECTS (parm)
+			/* If -ffloat-store specified, don't put explicit
+			   float variables into registers.  */
+			|| (flag_float_store
+			    && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))))
 	    {
 	      /* We can't use nominal_mode, because it will have been set to
 		 Pmode above.  We must use the actual mode of the parm.  */

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

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