Segher Boessenkool
Thu Dec 9 23:15:06 GMT 2021

On Wed, Dec 08, 2021 at 10:31:53PM -0500, Bradley Lucier wrote:
> Here's the kind of call I'd like turned into a tail call:
> return (*((___host*)((((long*)((___pc)-(1))) + (1 +((-2)))))))(___ps);

A simple quite standard indirect call.

> and it appears that gcc doesn't want to convert it to a tail call.   The 
> calling function has the same argument sequence.

There are more reasons.  Many are target-specific, and many are to do
with *other* things in the calling function.

> What should I search for in the .s file to see if this was tail called? 
>  It appears that the assembly code that this is translated into is:
> <stuff removed>
> 	movq	-864(%rbp), %rax
> 	subq	$9, %rax
> 	.loc 1 95837 157
> 	movq	(%rax), %rdx
> 	movq	-1032(%rbp), %rax
> 	movq	%rax, %rdi
> 	call	*%rdx
> .LVL0:
> .L1:
> 	.loc 1 95837 220
> 	movq	-24(%rbp), %rax
> 	subq	%fs:40, %rax
> 	je	.L17743
> 	call	__stack_chk_fail@PLT
> .L17743:
> 	movq	-8(%rbp), %rbx
> 	leave
> 	.cfi_def_cfa 7, 8
> 	ret

The "ret" says it is not a tail call.  Perhaps because it needs the
leave insn.  Oh, much more likely because __stack_chk_fail is noreturn.
We really need to fix that :-)

If you use -fdump-rtl-sibling-all the dump file might tell you more?

> PS:  LLVM seems to have a musttail attribute that you use at the call site:
> -#define ___PROPER_TAIL_CALL(call) __attribute__((musttail)) return call
> Does gcc have something like that?

I don't think so, no.

Note that this will fail unpredictably in the same way as what you
complained about before, and more so if you try to build for another
architecture than what the original author did.


More information about the Gcc-help mailing list