Skip to content

[AArch64][GISel] Incorrect ABI for calls with tail marker #70207

Closed
llvm/llvm-project-release-prs
#760
@nikic

Description

@nikic
; RUN: llc -O0 -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
declare void @func(i64, i64, i64, i64, i64, i128, i128)

define void @test(i128 %arg1, i128 %arg2) nounwind {
  tail call void @func(i64 0, i64 0, i64 0, i64 0, i64 0, i128 %arg1, i128 %arg2)
  ret void
}

This produces:

	sub	sp, sp, #64
	str	x30, [sp, #48]                  // 8-byte Folded Spill
	mov	x6, x0
	mov	x8, sp
	str	x1, [x8]
	str	x2, [x8, #16]
	str	x3, [x8, #32]
	mov	x4, xzr
	mov	x0, x4
	mov	x1, x4
	mov	x2, x4
	mov	x3, x4
	bl	func
	ldr	x30, [sp, #48]                  // 8-byte Folded Reload
	add	sp, sp, #64
	ret

Note that both of the i128 arguments get passed on the stack. Compare with the -global-isel=0 output:

	sub	sp, sp, #32
	str	x30, [sp, #16]                  // 8-byte Folded Spill
	mov	x7, x1
	mov	x6, x0
	mov	x8, sp
	str	x3, [x8, #8]
	str	x2, [x8]
	mov	x4, xzr
	mov	x0, x4
	mov	x1, x4
	mov	x2, x4
	mov	x3, x4
	bl	func
	ldr	x30, [sp, #16]                  // 8-byte Folded Reload
	add	sp, sp, #32
	ret

In this case the first i128 argument is passed in registers and only the second one on the stack.

Peculiarly, this does not happen when dropping the tail marker (which shouldn't make a difference as no actual tail call gets generated).

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions