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).
Confirmed.
I think this is a duplicate of #15473 (Sibcall optimization for libcalls). *** This bug has been marked as a duplicate of 15473 ***
It is not since this is not a libcall. At the tree level, we have a __builtin function which has been marked for tailcall.
Which is unlike the other case where we don't have a call at the tree level that gets marked as tail called.
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
> you are right, it's not a sibcall, my mistake. typo, I meant "libcall" not "sibcall"
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.
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).
(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.
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.
Fixed. Pre gets rid of the REALPART_EXPR/COMPLEX_EXPR now.