From feda184548246b017ca2b2338cb6b50293d5e3f6 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sat, 11 Oct 2003 03:53:05 +0000 Subject: [PATCH] builtins.c (builtin_mathfn_code): Generalize to check whether the call is to any built-in function by comparing... * builtins.c (builtin_mathfn_code): Generalize to check whether the call is to any built-in function by comparing the call's argument list against the builtin decl's function type. From-SVN: r72327 --- gcc/ChangeLog | 6 +++++ gcc/builtins.c | 72 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5859517feb3..5daf7a07dc7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-10-10 Roger Sayle + + * builtins.c (builtin_mathfn_code): Generalize to check whether + the call is to any built-in function by comparing the call's + argument list against the builtin decl's function type. + 2003-10-10 Roger Sayle * cse.c (constant_pool_entries_regcost): New global variable to diff --git a/gcc/builtins.c b/gcc/builtins.c index 8aabaa7754a..dc2008809a7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5318,15 +5318,16 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, } /* Determine whether a tree node represents a call to a built-in - math function. If the tree T is a call to a built-in function - taking a single real argument, then the return value is the - DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise - the return value is END_BUILTINS. */ + function. If the tree T is a call to a built-in function with + the right number of arguments of the appropriate types, return + the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. + Otherwise the return value is END_BUILTINS. */ enum built_in_function builtin_mathfn_code (tree t) { - tree fndecl, arglist; + tree fndecl, arglist, parmlist; + tree argtype, parmtype; if (TREE_CODE (t) != CALL_EXPR || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR) @@ -5334,36 +5335,57 @@ builtin_mathfn_code (tree t) fndecl = get_callee_fndecl (t); if (fndecl == NULL_TREE + || TREE_CODE (fndecl) != FUNCTION_DECL || ! DECL_BUILT_IN (fndecl) || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) return END_BUILTINS; arglist = TREE_OPERAND (t, 1); - if (! arglist - || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE) - return END_BUILTINS; - - arglist = TREE_CHAIN (arglist); - switch (DECL_FUNCTION_CODE (fndecl)) + parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + for (; parmlist; parmlist = TREE_CHAIN (parmlist)) { - case BUILT_IN_POW: - case BUILT_IN_POWF: - case BUILT_IN_POWL: - case BUILT_IN_ATAN2: - case BUILT_IN_ATAN2F: - case BUILT_IN_ATAN2L: - if (! arglist - || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE - || TREE_CHAIN (arglist)) - return END_BUILTINS; - break; + /* If a function doesn't take a variable number of arguments, + the last element in the list will have type `void'. */ + parmtype = TREE_VALUE (parmlist); + if (VOID_TYPE_P (parmtype)) + { + if (arglist) + return END_BUILTINS; + return DECL_FUNCTION_CODE (fndecl); + } - default: - if (arglist) + if (! arglist) return END_BUILTINS; - break; + + argtype = TREE_TYPE (TREE_VALUE (arglist)); + + if (SCALAR_FLOAT_TYPE_P (parmtype)) + { + if (! SCALAR_FLOAT_TYPE_P (argtype)) + return END_BUILTINS; + } + else if (COMPLEX_FLOAT_TYPE_P (parmtype)) + { + if (! COMPLEX_FLOAT_TYPE_P (argtype)) + return END_BUILTINS; + } + else if (POINTER_TYPE_P (parmtype)) + { + if (! POINTER_TYPE_P (argtype)) + return END_BUILTINS; + } + else if (INTEGRAL_TYPE_P (parmtype)) + { + if (! INTEGRAL_TYPE_P (argtype)) + return END_BUILTINS; + } + else + return END_BUILTINS; + + arglist = TREE_CHAIN (arglist); } + /* Variable-length argument list. */ return DECL_FUNCTION_CODE (fndecl); }