https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115815

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jamborm at gcc dot gnu.org

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
#1  0x00000000012b2089 in purge_all_uses (name=<ssa_name 0x7ffff7013708 1>, 
    killed_ssas=0x49329a0)
    at /space/rguenther/src/gcc/gcc/ipa-param-manipulation.cc:632
632               gcc_assert (lhs
633                           && (TREE_CODE (lhs) == SSA_NAME)
634                           && !gimple_vdef (stmt));
(gdb) p stmt
$1 = <gimple_return 0x7ffff6e81050>

we're having

__attribute__((destructor))
void b.isra ()
{
  int D.5155;
  int _1;
  int _2;
  int _3;

  <bb 3> [local count: 1073741824]:

  <bb 2> [local count: 966367642]:
  _1 = b ();
  _2 = 0;
  _3 = _1 + _2;
  return;

and purging uses of _1.  But then we do the same on the original function
which is

__attribute__((destructor))
int b ()
{
  int _1;
  int _2;
  int _4;

  <bb 2> [local count: 966367642]:
  _1 = b ();
  _2 = a;
  _4 = _1 + _2;
  return _4;

and that doesn't make sense.  I suppose the IPA transform got recursion
wrong somehow.  Of course this is an endless recursion but it computes
Inf * a.

Summary for node b/1:
  Returns value
  No parameter information.

  Summary for edge b/1->b/1:
    return value used only to compute caller return value

...

Evaluating analysis results for b/1
  Will remove return value.

  Created adjustments:
    m_always_copy_start: 0
    Will SKIP return.
                Accounting size:2.00, time:9.90 on predicate exec:(true)
  Created new node b.isra/3

which looks weird.

When I add a caller of 'b' then
this decision is no longer made, nor when I add a 'used' attribute.
The 'constructor' attribute makes the function prevail ('used')
(but it doesn't use the return value).

Modifying the testcase to

int a;
int  b() { return a + b(); }
int main()
{
  b ();
  return 0;
}

makes the same transform but since the original 'b' is elided the bug
doesn't trigger.

It seems that IPA doesn't consider the (recursive) call to 'b' from the
prevailing original function which does use the return value.

Reply via email to