Bug 32684 - Missed tail call with sin/cos and sincos pass
Summary: Missed tail call with sin/cos and sincos pass
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.3.0
: P3 enhancement
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: missed-optimization
Depends on:
Blocks: spec
  Show dependency treegraph
 
Reported: 2007-07-09 03:21 UTC by Andrew Pinski
Modified: 2014-12-01 05:17 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-07-09 09:34:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Pinski 2007-07-09 03:21:02 UTC
Testcase:
double _Complex quantum_cexp(double phi)
{
  return __builtin_cos(phi) + 1i * __builtin_sin(phi);
}

----- Cut ----
This shows up in libquantum (but after fixing a different issue which I will file seperately).
Comment 1 Richard Biener 2007-07-09 09:34:08 UTC
Confirmed.
Comment 2 chrbr 2007-10-09 08:36:23 UTC
I think this is a duplicate of #15473 (Sibcall optimization for libcalls).

*** This bug has been marked as a duplicate of 15473 ***
Comment 3 Andrew Pinski 2007-10-09 10:33:30 UTC
It is not since this is not a libcall.  At the tree level, we have a __builtin function which has been marked for tailcall.
Comment 4 Andrew Pinski 2007-10-09 10:34:16 UTC
Which is unlike the other case where we don't have a call at the tree level that gets marked as tail called.
Comment 5 chrbr 2007-10-09 13:12:23 UTC
you are right, it's not a sibcall, my mistake. 
But even at the tree level I still don't see the builtin marked as tailcall. On a reduced case when entering find_tail_calls I have

D.1177_2 = __builtin_cos (phi_1(D));
D.1176_3 = COMPLEX_EXPR <D.1177_2, 0.0>;
return D.1176_3;

and this is not recognized as a tailcall a candidate because the GIMPLE_MODIFY_STMT operand 1 is a complex_expr, not a call.

note that in the absence of complex_expr, such as a builtin_memset. all is fine
Comment 6 chrbr 2007-10-09 13:15:18 UTC
> you are right, it's not a sibcall, my mistake. 

typo, I meant "libcall" not "sibcall"
Comment 7 Andrew Pinski 2007-10-09 17:59:06 UTC
I get:
  sincostmp.5 = __builtin_cexpi (phi);
  REALPART_EXPR <<retval>> = REALPART_EXPR <sincostmp.5>;
  IMAGPART_EXPR <<retval>> = IMAGPART_EXPR <sincostmp.5>;
  return <retval>;

Which is created after the sincos pass as:
  sincostmp.5_7 = __builtin_cexpi (phi_1(D));
  D.1522_2 = REALPART_EXPR <sincostmp.5_7>;
  D.1524_4 = IMAGPART_EXPR <sincostmp.5_7>;
  REALPART_EXPR <<retval>> = D.1522_2;
  IMAGPART_EXPR <<retval>> = D.1524_4;

Which we don't recombine the real/img parts into just one assignment.
Comment 8 Richard Biener 2011-01-14 13:32:51 UTC
See also PR46926.  The flags controlling whether we can emit a call to
sincos need some work (but it's not exactly clear how it should work).
Comment 9 Richard Biener 2011-01-14 13:33:52 UTC
(In reply to comment #8)
> See also PR46926.  The flags controlling whether we can emit a call to
> sincos need some work (but it's not exactly clear how it should work).

Err - wrong bug.
Comment 10 Richard Biener 2011-01-14 13:51:31 UTC
Looking here again I can't see what tailcall you would expect.  Mainline
generates

complex double
quantum_cexp (double phi)
{
  complex double sincostmp.1;
  double D.2685;
  double D.2684;
  complex double D.2683;

<bb 2>:
  sincostmp.1_5 = __builtin_cexpi (phi_1(D));
  D.2684_2 = REALPART_EXPR <sincostmp.1_5>;
  D.2685_3 = IMAGPART_EXPR <sincostmp.1_5>;
  D.2683_4 = COMPLEX_EXPR <D.2684_2, D.2685_3>;
  return D.2683_4;

which we indeed do not optimize to just

  return __builtin_cexp1 (phi_1(D));

but in the end sincos doesn't have an ABI that allows for tailcalling
or sibcalling to it.

There is a missing folding of COMPLEX_EXPR <REALPART_EXPR <x>, IMAGPART_EXPR <x>> to x and SCCVN does not go the full way of combining binary expressions.
Comment 11 Andrew Pinski 2014-12-01 05:17:56 UTC
Fixed.  Pre gets rid of the REALPART_EXPR/COMPLEX_EXPR now.