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 <ebotca...@adacore.com> 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 <ebotca...@adacore.com> * 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); }