Files
clang-p2996/llvm/test/CodeGen/AArch64/sve-calling-convention-byref.ll
Eli Friedman bdd55b2f18 Fix the default alignment of i1 vectors.
Currently, the default alignment is much larger than the actual size of
the vector in memory.  Fix this to use a sane default.

For SVE, temporarily remove lowering of load/store operations for
predicates with less than 16 elements. The layout the backend was
assuming for SVE predicates with less than 16 elements doesn't agree
with the frontend. More work probably needs to be done here.

This change is, strictly speaking, not backwards-compatible at the
bitcode level. But probably nobody is actually depending on that; i1
vectors in memory are rare, and the code that does use them probably
ends up forcing the alignment to something sane anyway.  If we think
this is a concern, I can restrict this to scalable vectors for now
(where it's actually causing issues for me at the moment).

Differential Revision: https://reviews.llvm.org/D88994
2021-07-31 14:09:59 -07:00

119 lines
6.4 KiB
LLVM

; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s
; Test that z8 and z9, passed in by reference, are correctly loaded from x0 and x1.
; i.e. z0 = %z0
; :
; z7 = %z7
; x0 = &%z8
; x1 = &%z9
define aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_sve_arg(<vscale x 4 x i32> %z0, <vscale x 4 x i32> %z1, <vscale x 4 x i32> %z2, <vscale x 4 x i32> %z3, <vscale x 4 x i32> %z4, <vscale x 4 x i32> %z5, <vscale x 4 x i32> %z6, <vscale x 4 x i32> %z7, <vscale x 4 x i32> %z8, <vscale x 4 x i32> %z9) {
; CHECK: name: callee_with_many_sve_arg
; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = COPY $x1
; CHECK-DAG: [[PTRUE:%[0-9]+]]:ppr_3b = PTRUE_S 31
; CHECK-DAG: [[RES:%[0-9]+]]:zpr = LD1W_IMM killed [[PTRUE]], [[BASE]]
; CHECK-DAG: $z0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $z0
ret <vscale x 4 x i32> %z9
}
; Test that z8 and z9 are passed by reference.
define aarch64_sve_vector_pcs <vscale x 4 x i32> @caller_with_many_sve_arg(<vscale x 4 x i32> %z) {
; CHECK: name: caller_with_many_sve_arg
; CHECK: stack:
; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 16, alignment: 16,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK-DAG: [[PTRUE:%[0-9]+]]:ppr_3b = PTRUE_S 31
; CHECK-DAG: ST1W_IMM %{{[0-9]+}}, [[PTRUE]], %stack.1, 0
; CHECK-DAG: ST1W_IMM %{{[0-9]+}}, [[PTRUE]], %stack.0, 0
; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64sp = ADDXri %stack.1, 0
; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0
; CHECK-DAG: $x0 = COPY [[BASE1]]
; CHECK-DAG: $x1 = COPY [[BASE2]]
; CHECK-NEXT: BL @callee_with_many_sve_arg
; CHECK: RET_ReallyLR implicit $z0
%ret = call aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_sve_arg(<vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z)
ret <vscale x 4 x i32> %ret
}
; Test that p4 and p5, passed in by reference, are correctly loaded from register x0 and x1.
; i.e. p0 = %p0
; :
; p3 = %p3
; x0 = &%p4
; x1 = &%p5
define aarch64_sve_vector_pcs <vscale x 16 x i1> @callee_with_many_svepred_arg(<vscale x 16 x i1> %p0, <vscale x 16 x i1> %p1, <vscale x 16 x i1> %p2, <vscale x 16 x i1> %p3, <vscale x 16 x i1> %p4, <vscale x 16 x i1> %p5) {
; CHECK: name: callee_with_many_svepred_arg
; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = COPY $x1
; CHECK-DAG: [[RES:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0
; CHECK-DAG: $p0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $p0
ret <vscale x 16 x i1> %p5
}
; Test that p4 and p5 are passed by reference.
define aarch64_sve_vector_pcs <vscale x 16 x i1> @caller_with_many_svepred_arg(<vscale x 16 x i1> %p) {
; CHECK: name: caller_with_many_svepred_arg
; CHECK: stack:
; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 2, alignment: 2,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 2, alignment: 2,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK-DAG: STR_PXI %{{[0-9]+}}, %stack.0, 0
; CHECK-DAG: STR_PXI %{{[0-9]+}}, %stack.1, 0
; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0
; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64sp = ADDXri %stack.1, 0
; CHECK-DAG: $x0 = COPY [[BASE1]]
; CHECK-DAG: $x1 = COPY [[BASE2]]
; CHECK-NEXT: BL @callee_with_many_svepred_arg
; CHECK: RET_ReallyLR implicit $p0
%ret = call aarch64_sve_vector_pcs <vscale x 16 x i1> @callee_with_many_svepred_arg(<vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p)
ret <vscale x 16 x i1> %ret
}
; Test that z8 and z9, passed by reference, are loaded from a location that is passed on the stack.
; i.e. x0 = %x0
; :
; x7 = %x7
; z0 = %z0
; :
; z7 = %z7
; [sp] = &%z8
; [sp+8] = &%z9
;
define aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_gpr_sve_arg(i64 %x0, i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z1, <vscale x 4 x i32> %z2, <vscale x 4 x i32> %z3, <vscale x 4 x i32> %z4, <vscale x 4 x i32> %z5, <vscale x 4 x i32> %z6, <vscale x 4 x i32> %z7, <vscale x 2 x i64> %z8, <vscale x 4 x i32> %z9) {
; CHECK: name: callee_with_many_gpr_sve_arg
; CHECK: fixedStack:
; CHECK: - { id: 0, type: default, offset: 8, size: 8, alignment: 8, stack-id: default,
; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = LDRXui %fixed-stack.0, 0
; CHECK-DAG: [[PTRUE:%[0-9]+]]:ppr_3b = PTRUE_S 31
; CHECK-DAG: [[RES:%[0-9]+]]:zpr = LD1W_IMM killed [[PTRUE]], killed [[BASE]]
; CHECK-DAG: $z0 = COPY [[RES]]
; CHECK: RET_ReallyLR implicit $z0
ret <vscale x 4 x i32> %z9
}
; Test that z8 and z9 are passed by reference, where reference is passed on the stack.
define aarch64_sve_vector_pcs <vscale x 4 x i32> @caller_with_many_gpr_sve_arg(i64 %x, <vscale x 4 x i32> %z, <vscale x 2 x i64> %z2) {
; CHECK: name: caller_with_many_gpr_sve_arg
; CHECK: stack:
; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 16, alignment: 16,
; CHECK-NEXT: stack-id: scalable-vector
; CHECK-DAG: [[PTRUE_S:%[0-9]+]]:ppr_3b = PTRUE_S 31
; CHECK-DAG: [[PTRUE_D:%[0-9]+]]:ppr_3b = PTRUE_D 31
; CHECK-DAG: ST1D_IMM %{{[0-9]+}}, killed [[PTRUE_D]], %stack.0, 0
; CHECK-DAG: ST1W_IMM %{{[0-9]+}}, killed [[PTRUE_S]], %stack.1, 0
; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0
; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64common = ADDXri %stack.1, 0
; CHECK-DAG: [[SP:%[0-9]+]]:gpr64sp = COPY $sp
; CHECK-DAG: STRXui killed [[BASE1]], [[SP]], 0
; CHECK-DAG: STRXui killed [[BASE2]], [[SP]], 1
; CHECK: BL @callee_with_many_gpr_sve_arg
; CHECK: RET_ReallyLR implicit $z0
%ret = call aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_gpr_sve_arg(i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 2 x i64> %z2, <vscale x 4 x i32> %z)
ret <vscale x 4 x i32> %ret
}