This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

[PATCH] Fix __builtin_sincos{,f,l} type in Fortran FE (PR target/35662)


Hi!

sincos, sincosf and sincosl aren't variable length functions, but
the Fortran FE is prototyping them as such.  On some architectures
this makes no difference, on others results in less efficient, but
still working, code (e.g. on x86_64 this means loading a value into
%rax before the call uselessly), on others like mips-linux it
means arguments are passed in different registers than expected
(the first arg is for varargs functions passed in $4, while
sincosf expects it in $f12).

Starting regtest, ok for trunk/4.3 if it passes?

2008-04-15  Jakub Jelinek  <jakub@redhat.com>

	PR target/35662
	* f95-lang.c (gfc_init_builtin_functions): Make sure
	BUILT_IN_SINCOS{,F,L} types aren't varargs.

	* gfortran.dg/pr35662.f90: New test.

--- gcc/fortran/f95-lang.c.jj	2008-02-29 09:11:54.000000000 +0100
+++ gcc/fortran/f95-lang.c	2008-04-15 13:17:50.000000000 +0200
@@ -853,21 +853,21 @@ gfc_init_builtin_functions (void)
   ptype = build_pointer_type (float_type_node);
   tmp = tree_cons (NULL_TREE, float_type_node,
 		   tree_cons (NULL_TREE, ptype,
-		   	      build_tree_list (NULL_TREE, ptype)));
+		   	      tree_cons (NULL_TREE, ptype, void_list_node)));
   func_float_floatp_floatp =
     build_function_type (void_type_node, tmp);
 
   ptype = build_pointer_type (double_type_node);
   tmp = tree_cons (NULL_TREE, double_type_node,
 		   tree_cons (NULL_TREE, ptype,
-		   	      build_tree_list (NULL_TREE, ptype)));
+		   	      tree_cons (NULL_TREE, ptype, void_list_node)));
   func_double_doublep_doublep =
     build_function_type (void_type_node, tmp);
 
   ptype = build_pointer_type (long_double_type_node);
   tmp = tree_cons (NULL_TREE, long_double_type_node,
 		   tree_cons (NULL_TREE, ptype,
-		   	      build_tree_list (NULL_TREE, ptype)));
+		   	      tree_cons (NULL_TREE, ptype, void_list_node)));
   func_longdouble_longdoublep_longdoublep =
     build_function_type (void_type_node, tmp);
 
--- gcc/testsuite/gfortran.dg/pr35662.f90.jj	2008-04-15 13:44:17.000000000 +0200
+++ gcc/testsuite/gfortran.dg/pr35662.f90	2008-04-15 13:44:09.000000000 +0200
@@ -0,0 +1,20 @@
+! PR target/35662
+! { dg-do run }
+! { dg-options "-O1" }
+
+subroutine f(x, y, z)
+  real, intent (in) :: x
+  real, intent (out) :: y, z
+  y = sin (x)
+  z = cos (x)
+end subroutine f
+
+program pr35662
+  real :: x, y, z
+  x = 3.1415926535897932384626433832795029
+  call f (x, y, z)
+  if (abs (y) > 1.0e-5 .or. abs (z + 1.0) > 1.0e-5) call abort
+  x = x / 2.0
+  call f (x, y, z)
+  if (abs (y - 1.0) > 1.0e-5 .or. abs (z) > 1.0e-5) call abort
+end program pr35662

	Jakub


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