From 34a24c113b24556bf858a0614491beb85152646e Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Thu, 15 Mar 2007 20:14:49 +0000 Subject: [PATCH] re PR middle-end/29719 (newlib targets ICEs in expand_builtin_int_roundingfn) 2007-03-15 Richard Guenther PR middle-end/29719 PR middle-end/31161 * builtins.c (expand_builtin_int_roundingfn): Always fall back to floor/ceil and its variants even if they may be not available. (expand_builtin_cexpi): As a fallback if we don't have builtins for sincos or cexp create a function declaration for cexp and expand to a call to that. From-SVN: r122958 --- gcc/ChangeLog | 11 ++++++++ gcc/builtins.c | 71 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32724cc1c21..760143ef04f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2007-03-15 Richard Guenther + + PR middle-end/29719 + PR middle-end/31161 + * builtins.c (expand_builtin_cexpi): As a fallback if we + don't have builtins for sincos or cexp create a function + declaration for cexp and expand to a call to that. + (expand_builtin_int_roundingfn): Always fall + back to floor/ceil and its variants even if they may be + not available. + 2007-03-15 Steven Bosscher PR middle-end/31159 diff --git a/gcc/builtins.c b/gcc/builtins.c index 676b9caba66..1e45ed05271 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2376,9 +2376,6 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget) tree call, fn = NULL_TREE, narg; tree ctype = build_complex_type (type); - /* We can expand via the C99 cexp function. */ - gcc_assert (TARGET_C99_FUNCTIONS); - if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) fn = built_in_decls[BUILT_IN_CEXPF]; else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) @@ -2387,6 +2384,26 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget) fn = built_in_decls[BUILT_IN_CEXPL]; else gcc_unreachable (); + + /* If we don't have a decl for cexp create one. This is the + friendliest fallback if the user calls __builtin_cexpi + without full target C99 function support. */ + if (fn == NULL_TREE) + { + tree fntype; + const char *name = NULL; + + if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF) + name = "cexpf"; + else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI) + name = "cexp"; + else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL) + name = "cexpl"; + + fntype = build_function_type_list (ctype, ctype, NULL_TREE); + fn = build_fn_decl (name, fntype); + } + narg = fold_build2 (COMPLEX_EXPR, ctype, build_real (type, dconst0), arg); @@ -2480,9 +2497,51 @@ expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget) /* Fall back to floating point rounding optab. */ fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn); - /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS. - ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */ - gcc_assert (fallback_fndecl != NULL_TREE); + + /* For non-C99 targets we may end up without a fallback fndecl here + if the user called __builtin_lfloor directly. In this case emit + a call to the floor/ceil variants nevertheless. This should result + in the best user experience for not full C99 targets. */ + if (fallback_fndecl == NULL_TREE) + { + tree fntype; + const char *name = NULL; + + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_LCEIL: + case BUILT_IN_LLCEIL: + name = "ceil"; + break; + case BUILT_IN_LCEILF: + case BUILT_IN_LLCEILF: + name = "ceilf"; + break; + case BUILT_IN_LCEILL: + case BUILT_IN_LLCEILL: + name = "ceill"; + break; + case BUILT_IN_LFLOOR: + case BUILT_IN_LLFLOOR: + name = "floor"; + break; + case BUILT_IN_LFLOORF: + case BUILT_IN_LLFLOORF: + name = "floorf"; + break; + case BUILT_IN_LFLOORL: + case BUILT_IN_LLFLOORL: + name = "floorl"; + break; + default: + gcc_unreachable (); + } + + fntype = build_function_type_list (TREE_TYPE (arg), + TREE_TYPE (arg), NULL_TREE); + fallback_fndecl = build_fn_decl (name, fntype); + } + exp = build_call_expr (fallback_fndecl, 1, arg); tmp = expand_normal (exp);