PATCH: Fix builtins-18.c and builtins-20.c on arm-none-elf

Mark Mitchell mark@codesourcery.com
Wed Dec 24 14:06:00 GMT 2003


There were two problems with these tests on arm-none-elf (and probably
on other platforms that use libcalls for some floating-point
operations).

The first problem was that expand_call was not creating useful
REG_RETVAL notes for calls to sqrt.  It was doing like so:

    (insn_list:REG_RETVAL 39 (expr_list:REG_EQUAL (expr_list (symbol_ref:SI ("sqrt") <function_decl 0x4037bca8 __builtin_sqrt>)

rather than the much more useful version generated for a libcall to an
addition routine:

    (insn_list:REG_RETVAL 29 (expr_list:REG_EQUAL (plus:DF (reg:DF 77)
                (reg:DF 79))

CSE is not smart enough to handle the former form (although perhaps it
could be taught to be).  This patch has expand_call generate a
REG_RETVAL note that uses the SQRT RTL operation.

A second problem was that these tests omit certain features on systems
that do not have full C99 support.  One of the tests was not correctly
omitting tests for float variants of library functions on non-C99
systems.  Neither test was correctly recognizing that newlib is not a
C99 library. 

Really, these tests are misdesigned; the C99 bits should be split out
into separate tests.

(I was also amused while playing with these tests to realize that on
x86 Red Hat 8.0 include <math.h> causes GCC to generate worse code for
these tests; the inline versions of the math functions do not permit
the same simplifications as the builtins.  Hopefully the glibc people
will remove the inline math functions, if they have not already done
so.)

Tested on arm-none-elf and lightly on i686-pc-linux-gnu, applied on
the mainline and the csl-arm-branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-12-23  Mark Mitchell  <mark@codesourcery.com>

	* calls.c (expand_call): Recognize calls to "sqrt" and create
	corresponding notes.

2003-12-23  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/bprob/bprob.exp: Load target-supports.exp
	* g77.dg/bprob/bprob.exp: Likewise.
	* gcc.misc-tests/bprob.exp: Likewise.
	* gcc.dg/builtins-18.c: Use builtins-config.h.  Do not test float
	variants on systems where the library does not provide that
	functionality.
	* gcc.dg/builtins-20.c: Use builtins-config.h.
	* gcc.dg/builtins-config.h: New file.

Index: calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.311
diff -c -5 -p -r1.311 calls.c
*** calls.c	18 Dec 2003 05:50:43 -0000	1.311
--- calls.c	24 Dec 2003 06:51:10 -0000
*************** expand_call (tree exp, rtx target, int i
*** 3148,3173 ****
  	      /* Mark the return value as a pointer if needed.  */
  	      if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
  		mark_reg_pointer (temp,
  				  TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))));
  
- 	      /* Construct an "equal form" for the value which mentions all the
- 		 arguments in order as well as the function name.  */
- 	      for (i = 0; i < num_actuals; i++)
- 		note = gen_rtx_EXPR_LIST (VOIDmode,
- 					  args[i].initial_value, note);
- 	      note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
- 
  	      end_sequence ();
! 
! 	      if (flags & ECF_PURE)
! 		note = gen_rtx_EXPR_LIST (VOIDmode,
  			gen_rtx_USE (VOIDmode,
  				     gen_rtx_MEM (BLKmode,
  						  gen_rtx_SCRATCH (VOIDmode))),
  			note);
! 
  	      emit_libcall_block (insns, temp, valreg, note);
  
  	      valreg = temp;
  	    }
  	}
--- 3148,3184 ----
  	      /* Mark the return value as a pointer if needed.  */
  	      if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
  		mark_reg_pointer (temp,
  				  TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))));
  
  	      end_sequence ();
! 	      if (flag_unsafe_math_optimizations
! 		  && fndecl
! 		  && DECL_BUILT_IN (fndecl)
! 		  && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRT
! 		      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTF
! 		      || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTL))
! 		note = gen_rtx_fmt_e (SQRT, 
! 				      GET_MODE (temp), 
! 				      args[0].initial_value);
! 	      else
! 		{
! 		  /* Construct an "equal form" for the value which
! 		     mentions all the arguments in order as well as
! 		     the function name.  */
! 		  for (i = 0; i < num_actuals; i++)
! 		    note = gen_rtx_EXPR_LIST (VOIDmode,
! 					      args[i].initial_value, note);
! 		  note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
! 		  
! 		  if (flags & ECF_PURE)
! 		    note = gen_rtx_EXPR_LIST (VOIDmode,
  			gen_rtx_USE (VOIDmode,
  				     gen_rtx_MEM (BLKmode,
  						  gen_rtx_SCRATCH (VOIDmode))),
  			note);
! 		}
  	      emit_libcall_block (insns, temp, valreg, note);
  
  	      valreg = temp;
  	    }
  	}
Index: testsuite/g++.dg/bprob/bprob.exp
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/bprob/bprob.exp,v
retrieving revision 1.6
diff -c -5 -p -r1.6 bprob.exp
*** testsuite/g++.dg/bprob/bprob.exp	23 Dec 2003 23:55:05 -0000	1.6
--- testsuite/g++.dg/bprob/bprob.exp	24 Dec 2003 06:51:20 -0000
***************
*** 15,24 ****
--- 15,26 ----
  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  #
  # Test the functionality of programs compiled with profile-directed block
  # ordering using -fprofile-arcs followed by -fbranch-probabilities.
  
+ load_lib target-supports.exp
+ 
  # Some targets don't have any implementation of __bb_init_func or are
  # missing other needed machinery.
  if { ![check_profiling_available] } {
      return
  }
Index: testsuite/g77.dg/bprob/bprob.exp
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g77.dg/bprob/bprob.exp,v
retrieving revision 1.6
diff -c -5 -p -r1.6 bprob.exp
*** testsuite/g77.dg/bprob/bprob.exp	23 Dec 2003 23:55:05 -0000	1.6
--- testsuite/g77.dg/bprob/bprob.exp	24 Dec 2003 06:51:21 -0000
***************
*** 15,24 ****
--- 15,26 ----
  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  
  # Test the functionality of programs compiled with profile-directed block
  # ordering using -fprofile-arcs followed by -fbranch-probabilities.
  
+ load_lib target-supports.exp
+ 
  # Some targets don't have any implementation of __bb_init_func or are
  # missing other needed machinery.
  if { ![check_profiling_available] } {
      return
  }
Index: testsuite/gcc.dg/builtins-18.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/builtins-18.c,v
retrieving revision 1.2
diff -c -5 -p -r1.2 builtins-18.c
*** testsuite/gcc.dg/builtins-18.c	20 Oct 2003 06:15:23 -0000	1.2
--- testsuite/gcc.dg/builtins-18.c	24 Dec 2003 06:51:21 -0000
***************
*** 6,20 ****
     Written by Roger Sayle, 1st June 2003.  */
  
  /* { dg-do link } */
  /* { dg-options "-O2 -ffast-math" } */
  
! 
! /* Solaris doesn't have the entire C99 runtime.  */
! #if !defined(sun)
! #define HAVE_C99_RUNTIME
! #endif
  
  extern void link_error(void);
  
  extern float cabsf (float _Complex);
  extern double cabs (double _Complex);
--- 6,16 ----
     Written by Roger Sayle, 1st June 2003.  */
  
  /* { dg-do link } */
  /* { dg-options "-O2 -ffast-math" } */
  
! #include "builtins-config.h"
  
  extern void link_error(void);
  
  extern float cabsf (float _Complex);
  extern double cabs (double _Complex);
*************** main (void)
*** 27,45 ****
--- 23,43 ----
       optimization.  */
    float _Complex fc = 3.0F + 4.0iF;
    double _Complex dc = 3.0 + 4.0i;
    long double _Complex ldc = 3.0L + 4.0iL;
  
+ #ifdef HAVE_C99_RUNTIME
    /* Test floats.  */
    if (cabsf (fc) != 5.0F)
      link_error ();
    if (__builtin_cabsf (fc) != 5.0F)
      link_error ();
    if (cabsf (3.0F + 4.0iF) != 5.0F)
      link_failure ();
    if (__builtin_cabsf (3.0F + 4.0iF) != 5.0F)
      link_failure ();
+ #endif
  
    /* Test doubles.  */
    if (cabs (dc) != 5.0)
      link_error ();
    if (__builtin_cabs (dc) != 5.0)
Index: testsuite/gcc.dg/builtins-20.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/builtins-20.c,v
retrieving revision 1.2
diff -c -5 -p -r1.2 builtins-20.c
*** testsuite/gcc.dg/builtins-20.c	20 Oct 2003 06:15:23 -0000	1.2
--- testsuite/gcc.dg/builtins-20.c	24 Dec 2003 06:51:21 -0000
***************
*** 6,20 ****
     Written by Roger Sayle, 8th June 2003.  */
  
  /* { dg-do link } */
  /* { dg-options "-O2 -ffast-math" } */
  
! 
! /* Solaris doesn't have the entire C99 runtime.  */
! #if !defined(sun)
! #define HAVE_C99_RUNTIME
! #endif
  
  extern void link_error(void);
  
  void test1(double x)
  {
--- 6,16 ----
     Written by Roger Sayle, 8th June 2003.  */
  
  /* { dg-do link } */
  /* { dg-options "-O2 -ffast-math" } */
  
! #include "builtins-config.h"
  
  extern void link_error(void);
  
  void test1(double x)
  {
Index: testsuite/gcc.dg/builtins-config.h
===================================================================
RCS file: testsuite/gcc.dg/builtins-config.h
diff -N testsuite/gcc.dg/builtins-config.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/builtins-config.h	24 Dec 2003 06:51:21 -0000
***************
*** 0 ****
--- 1,29 ----
+ /* Copyright (C) 2003 Free Software Foundation.
+ 
+    Define macros useful in tests for bulitin functions.  */
+ 
+ /* Define HAVE_C99_RUNTIME if the entire C99 runtime is available on
+    the target system.  The value of HAVE_C99_RUNTIME should be the
+    same as the value of TARGET_C99_FUNCTIONS in the GCC machine
+    description.  (Perhaps GCC should predefine a special macro
+    indicating whether or not TARGET_C99_FUNCTIONS is set, but it does
+    not presently do that.)  */
+ 
+ #if defined(sun)
+ /* Solaris doesn't have the entire C99 runtime.  */
+ #else
+ /* Newlib has the "f" variants of the math functions, but not the "l"
+    variants.  TARGET_C99_FUNCTIONS is only defined if all C99
+    functions are present.  Therefore, on systems using newlib, tests
+    of builtins will fail for both the "f" and the "l" variants, and we
+    should therefore not define HAVE_C99_RUNTIME.  Including <limits.h>
+    gives us a way of seeing if _NEWLIB_VERSION is defined.  Include
+    <math.h> would work too, but the GLIBC math inlines cause us to
+    generate inferior code, which causes the test to fail, so it is
+    not safe to include <math.h>.  */
+ #include <limits.h>
+ #ifdef _NEWLIB_VERSION
+ #else
+ #define HAVE_C99_RUNTIME
+ #endif
+ #endif
Index: testsuite/gcc.misc-tests/bprob.exp
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.misc-tests/bprob.exp,v
retrieving revision 1.7
diff -c -5 -p -r1.7 bprob.exp
*** testsuite/gcc.misc-tests/bprob.exp	23 Dec 2003 23:55:06 -0000	1.7
--- testsuite/gcc.misc-tests/bprob.exp	24 Dec 2003 06:51:21 -0000
***************
*** 15,24 ****
--- 15,26 ----
  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
  
  # Test the functionality of programs compiled with profile-directed block
  # ordering using -fprofile-arcs followed by -fbranch-probabilities.
  
+ load_lib target-supports.exp
+ 
  # Some targets don't have any implementation of __bb_init_func or are
  # missing other needed machinery.
  if { ![check_profiling_available] } {
      return
  }



More information about the Gcc-patches mailing list