Skip to content

[LLVM][MIPS] Sibling calls push/pop stack #165906

@ameisen

Description

@ameisen

At present, tail call optimizations do not work at all with or without the mips-tail-calls flag being set. This is related to and dependent upon, but distinct from, #161193.

This issue is being reported with PR #161860 by @djtodoro, as it makes tail calls functional at all in MIPS.

With said PR, sibling calls are not being optimized - the jump-link instructions is being pushed to the end and replaced with a jump and the jump-return removed, but the stack is still being set-up and torn-down.

__attribute__((noinline))
int foo0()
{
	volatile int a;
	return a += 1;
}

int bar0()
{
	return foo0();
}

with tail calls disabled (-std=gnu++23 -O3 -march=mips32r6 -fno-PIC -mllvm -mips-tail-calls=0):

	addiu	$sp, $sp, -24
	sw	$ra, 20($sp)                    # 4-byte Folded Spill
	sw	$fp, 16($sp)                    # 4-byte Folded Spill
	move	$fp, $sp
	jal	_Z4foo0v
	nop
	move	$sp, $fp
	lw	$fp, 16($sp)                    # 4-byte Folded Reload
	lw	$ra, 20($sp)                    # 4-byte Folded Reload
	addiu	$sp, $sp, 24
	jrc	$ra

with tail calls enabled (-std=gnu++23 -O3 -march=mips32r6 -fno-PIC -mllvm -mips-tail-calls=1):

	addiu	$sp, $sp, -8
	sw	$ra, 4($sp)                     # 4-byte Folded Spill
	sw	$fp, 0($sp)                     # 4-byte Folded Spill
	move	$fp, $sp
	move	$sp, $fp
	lw	$fp, 0($sp)                     # 4-byte Folded Reload
	lw	$ra, 4($sp)                     # 4-byte Folded Reload
	j	_Z4foo0v
	addiu	$sp, $sp, 8

What is expected:

	j	_Z4foo0v
	nop

or

	bc	_Z4foo0v

So, it's moving the j to the end, but it's not cleaning up the stack changes that were around the jump. Everything in here but the j could be removed (with a nop, but the j should be replaced with a bc anyways, see #165634), but this effectively is generating a rather messed up function.

A significant amount of logic for handling this issue is present in LowerCall for PPC and for AArch64 (and the rest), but is missing in the MIPS version.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions