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

Reply via email to