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:
Jakub Jelinek 2012-03-15 14:30:04 +01:00 committed by Jakub Jelinek
parent b3781fcb26
commit ff63ac4d66
4 changed files with 90 additions and 26 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.

View 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" } } */