Hi,
this is the ICE during the build of the Ada runtime on x86-64/Windows: the
compiler stops on the assertion in declare_return_variable:
var = return_slot;
gcc_assert (TREE_CODE (var) != SSA_NAME);
The problem stems for the fnsplit pass: it turns
P.Sin (const long_long_float x)
{
long_long_float _3;
boolean _4;
q__double _9;
<bb 2>:
_3 = ABS_EXPR <x_2(D)>;
_4 = _3 < 1.0e+0;
if (_4 != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
<retval> = x_2(D);
goto <bb 5>;
<bb 4>:
_9 = q.sin (x_2(D));
<retval> = _9;
<bb 5>:
return <retval>;
}
into
P.Sin (const long_long_float x)
{
long_long_float _3;
boolean _4;
<bb 2>:
_3 = ABS_EXPR <x_2(D)>;
_4 = _3 < 1.0e+0;
if (_4 != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
<retval> = x_2(D);
goto <bb 5>;
<bb 4>:
<retval> = p.sin.part (x_2(D)); [return slot optimization]
<bb 5>:
return <retval>;
}
Note the RSO flag on the call to the split part: it's bogus since the return
type is scalar:
<real_type 0x7ffff6da02a0 long_long_float sizes-gimplified visited XF>
Fixed by checking that either the type of the result is not is_gimple_reg_type
or the result is passed by reference before setting the RSO flag.
Tested on x86_64-suse-linux, OK for the mainline?
2013-01-01 Eric Botcazou <[email protected]>
PR tree-optimization/56424
* ipa-split.c (split_function): Do not set the RSO flag if result is
not by reference and its type is not a register type.
2013-01-01 Eric Botcazou <[email protected]>
* gcc.dg/pr56424.c: New test.
--
Eric Botcazou
Index: ipa-split.c
===================================================================
--- ipa-split.c (revision 196253)
+++ ipa-split.c (working copy)
@@ -1309,7 +1309,9 @@ split_function (struct split_point *spli
so return slot optimization is always possible. Moreover this is
required to make DECL_BY_REFERENCE work. */
if (aggregate_value_p (DECL_RESULT (current_function_decl),
- TREE_TYPE (current_function_decl)))
+ TREE_TYPE (current_function_decl))
+ && (!is_gimple_reg_type (TREE_TYPE (DECL_RESULT (current_function_decl)))
+ || DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))))
gimple_call_set_return_slot_opt (call, true);
/* Update return value. This is bit tricky. When we do not return,
/* PR tree-optimization/56424 */
/* { dg-do compile } */
/* { dg-options "-O2 -fexceptions -fnon-call-exceptions" } */
extern long double cosl (long double);
extern long double sinl (long double);
extern long double reml (long double, long double);
long double my_cos (long double arg)
{
return cosl (arg);
}
long double my_sin (long double arg)
{
if (__builtin_fabs (arg) < 1.0)
return arg;
return sinl (arg);
}
long double my_cot (long double arg, long double cycle)
{
long double t = reml (arg, cycle);
return my_cos (t) / my_sin (t);
}
long double my_tan (long double arg, long double cycle)
{
long double t = reml (arg, cycle);
return my_sin (t) / my_cos (t);
}