re PR middle-end/52592 (compilation failure with undefined reference to `__builtin_iround')
PR middle-end/52592 * builtins.c (expand_builtin_int_roundingfn_2): If expanding BUILT_IN_IR{INT,OUND}* using optab fails, emit lr{int,ound}* calls instead of __builtin_ir{int,ound}*. * gcc.dg/pr52592.c: New test. Co-Authored-By: Andrew Pinski <apinski@cavium.com> From-SVN: r185431
This commit is contained in:
parent
b3781fcb26
commit
ff63ac4d66
@ -1,3 +1,11 @@
|
||||
2012-03-15 Jakub Jelinek <jakub@redhat.com>
|
||||
Andrew Pinski <apinski@cavium.com>
|
||||
|
||||
PR middle-end/52592
|
||||
* builtins.c (expand_builtin_int_roundingfn_2): If expanding
|
||||
BUILT_IN_IR{INT,OUND}* using optab fails, emit lr{int,ound}*
|
||||
calls instead of __builtin_ir{int,ound}*.
|
||||
|
||||
2012-03-15 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
|
||||
|
||||
* doc/sourcebuild.texi (cleanup-modules, keep-modules): Update
|
||||
|
@ -2841,10 +2841,7 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
|
||||
tree fndecl = get_callee_fndecl (exp);
|
||||
tree arg;
|
||||
enum machine_mode mode;
|
||||
|
||||
/* There's no easy way to detect the case we need to set EDOM. */
|
||||
if (flag_errno_math)
|
||||
return NULL_RTX;
|
||||
enum built_in_function fallback_fn = BUILT_IN_NONE;
|
||||
|
||||
if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
|
||||
gcc_unreachable ();
|
||||
@ -2854,46 +2851,78 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
|
||||
switch (DECL_FUNCTION_CODE (fndecl))
|
||||
{
|
||||
CASE_FLT_FN (BUILT_IN_IRINT):
|
||||
fallback_fn = BUILT_IN_LRINT;
|
||||
/* FALLTHRU */
|
||||
CASE_FLT_FN (BUILT_IN_LRINT):
|
||||
CASE_FLT_FN (BUILT_IN_LLRINT):
|
||||
builtin_optab = lrint_optab; break;
|
||||
builtin_optab = lrint_optab;
|
||||
break;
|
||||
|
||||
CASE_FLT_FN (BUILT_IN_IROUND):
|
||||
fallback_fn = BUILT_IN_LROUND;
|
||||
/* FALLTHRU */
|
||||
CASE_FLT_FN (BUILT_IN_LROUND):
|
||||
CASE_FLT_FN (BUILT_IN_LLROUND):
|
||||
builtin_optab = lround_optab; break;
|
||||
builtin_optab = lround_optab;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* There's no easy way to detect the case we need to set EDOM. */
|
||||
if (flag_errno_math && fallback_fn == BUILT_IN_NONE)
|
||||
return NULL_RTX;
|
||||
|
||||
/* Make a suitable register to place result in. */
|
||||
mode = TYPE_MODE (TREE_TYPE (exp));
|
||||
|
||||
target = gen_reg_rtx (mode);
|
||||
|
||||
/* Wrap the computation of the argument in a SAVE_EXPR, as we may
|
||||
need to expand the argument again. This way, we will not perform
|
||||
side-effects more the once. */
|
||||
CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
|
||||
|
||||
op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
start_sequence ();
|
||||
|
||||
if (expand_sfix_optab (target, op0, builtin_optab))
|
||||
/* There's no easy way to detect the case we need to set EDOM. */
|
||||
if (!flag_errno_math)
|
||||
{
|
||||
/* Output the entire sequence. */
|
||||
insns = get_insns ();
|
||||
target = gen_reg_rtx (mode);
|
||||
|
||||
/* Wrap the computation of the argument in a SAVE_EXPR, as we may
|
||||
need to expand the argument again. This way, we will not perform
|
||||
side-effects more the once. */
|
||||
CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
|
||||
|
||||
op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
start_sequence ();
|
||||
|
||||
if (expand_sfix_optab (target, op0, builtin_optab))
|
||||
{
|
||||
/* Output the entire sequence. */
|
||||
insns = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn (insns);
|
||||
return target;
|
||||
}
|
||||
|
||||
/* If we were unable to expand via the builtin, stop the sequence
|
||||
(without outputting the insns) and call to the library function
|
||||
with the stabilized argument list. */
|
||||
end_sequence ();
|
||||
emit_insn (insns);
|
||||
return target;
|
||||
}
|
||||
|
||||
/* If we were unable to expand via the builtin, stop the sequence
|
||||
(without outputting the insns) and call to the library function
|
||||
with the stabilized argument list. */
|
||||
end_sequence ();
|
||||
if (fallback_fn != BUILT_IN_NONE)
|
||||
{
|
||||
/* Fall back to rounding to long int. Use implicit_p 0 - for non-C99
|
||||
targets, (int) round (x) should never be transformed into
|
||||
BUILT_IN_IROUND and if __builtin_iround is called directly, emit
|
||||
a call to lround in the hope that the target provides at least some
|
||||
C99 functions. This should result in the best user experience for
|
||||
not full C99 targets. */
|
||||
tree fallback_fndecl = mathfn_built_in_1 (TREE_TYPE (arg),
|
||||
fallback_fn, 0);
|
||||
|
||||
exp = build_call_nofold_loc (EXPR_LOCATION (exp),
|
||||
fallback_fndecl, 1, arg);
|
||||
|
||||
target = expand_call (exp, NULL_RTX, target == const0_rtx);
|
||||
return convert_to_mode (mode, target, 0);
|
||||
}
|
||||
|
||||
target = expand_call (exp, target, target == const0_rtx);
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2012-03-15 Jakub Jelinek <jakub@redhat.com>
|
||||
Andrew Pinski <apinski@cavium.com>
|
||||
|
||||
PR middle-end/52592
|
||||
* gcc.dg/pr52592.c: New test.
|
||||
|
||||
2012-03-15 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
|
||||
|
||||
* gfortran.fortran-torture/compile/compile.exp: Simplify.
|
||||
|
21
gcc/testsuite/gcc.dg/pr52592.c
Normal file
21
gcc/testsuite/gcc.dg/pr52592.c
Normal file
@ -0,0 +1,21 @@
|
||||
/* PR middle-end/52592 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -O2 -ffast-math" } */
|
||||
|
||||
#define T(type, name) \
|
||||
type name (type); \
|
||||
__attribute__((cold)) \
|
||||
int f##name (type x) \
|
||||
{ \
|
||||
return (int) name (x); \
|
||||
}
|
||||
|
||||
T (double, round)
|
||||
T (float, roundf)
|
||||
T (long double, roundl)
|
||||
T (double, rint)
|
||||
T (float, rintf)
|
||||
T (long double, rintl)
|
||||
|
||||
/* { dg-final { scan-assembler-not "__builtin_iround" } } */
|
||||
/* { dg-final { scan-assembler-not "__builtin_irint" } } */
|
Loading…
x
Reference in New Issue
Block a user