[RFH] Folding of (int)round to lround (and friends)

Richard Guenther rguenther@suse.de
Tue Dec 6 12:22:00 GMT 2005


The patch below implements folding of integer conversions of
the rounding functions to the specific C99 routines.  And there
is the problem - given suitable expanders, code generated for
lround can be a lot better than for (int)round, but lround is
only available from C99 (and maybe doesn't have a library fallback).
So with the patch below I get

#include <math.h>

int foo(double x)
{
  return round(x);
}

> gcc -c -O2 t.c
t.c: In function 'foo':
t.c:5: warning: incompatible implicit declaration of built-in function 
'llround'

which I can only avoid with -std=c99.  How do we generally deal with
this?  Not do the transformation if !c99?

Thanks,
Richard.


2005-12-06  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (fold_unary): Fold integer conversion from
	ceil, floor, rint, round to ll{ceil,floor,rint,round}.
	Fold conversion to integer with precision smaller or equal
	to that of long from ll{ceil,floor,rint,round} to
	l{ceil,floor,rint,round}.


Index: fold-const.c
===================================================================
*** fold-const.c	(revision 108107)
--- fold-const.c	(working copy)
*************** fold_unary (enum tree_code code, tree ty
*** 7009,7014 ****
--- 7009,7059 ----
  			   TREE_OPERAND (arg0, 1));
  	}
  
+       /* Conversions of certain builtin functions to integer types.  */
+       if (TREE_CODE (op0) == CALL_EXPR
+ 	  && TREE_CODE (type) == INTEGER_TYPE)
+ 	{
+ 	  enum built_in_function fcode = builtin_mathfn_code (op0);
+ 	  tree args = TREE_OPERAND (op0, 1);
+ 	  tree newfn, tmp;
+ 	  switch (fcode)
+ 	    {
+ 	    /* Handle integer conversion of ceil, floor, rint, round.  */
+ #define HANDLE_BUILT_IN(x) \
+             CASE_FLT_FN (BUILT_IN_ ## x): \
+ 	      newfn = mathfn_built_in (TREE_TYPE (op0), BUILT_IN_LL ## x); \
+ 	      tmp = build_function_call_expr (newfn, args); \
+ 	      return fold_convert (type, tmp);
+ 	    HANDLE_BUILT_IN (CEIL)
+ 	    HANDLE_BUILT_IN (FLOOR)
+ 	    HANDLE_BUILT_IN (RINT)
+ 	    HANDLE_BUILT_IN (ROUND)
+ #undef HANDLE_BUILT_IN
+ 	    default:
+ 	      break;
+ 	    }
+ 	    /* Handle conversion to lower precision integer type of
+ 	       llceil, llfloor, llrint and llround.  */
+ 	    if (TYPE_PRECISION (type) <= TYPE_PRECISION (long_integer_type_node))
+ 	      {
+ 		switch (fcode)
+ 		  {
+ #define HANDLE_BUILT_IN(x) \
+ 		  CASE_FLT_FN (BUILT_IN_LL ## x): \
+ 		    newfn = mathfn_built_in (TREE_TYPE (TREE_VALUE (args)), BUILT_IN_L ## x); \
+ 		    tmp = build_function_call_expr (newfn, args); \
+ 		    return fold_convert (type, tmp);
+ 		  HANDLE_BUILT_IN (CEIL)
+ 		  HANDLE_BUILT_IN (FLOOR)
+ 		  HANDLE_BUILT_IN (RINT)
+ 		  HANDLE_BUILT_IN (ROUND)
+ #undef HANDLE_BUILT_IN
+ 		  default:
+ 		    break;
+ 		  }
+ 	      }
+ 	}
+ 
        tem = fold_convert_const (code, type, arg0);
        return tem ? tem : NULL_TREE;
  



More information about the Gcc-patches mailing list