forked from OSchip/llvm-project
[RISCV] Support passing scalable vectur values through the stack.
After consuming all vector registers, the scalable vector values will be passed indirectly. The pointer values will be saved in general registers. If all general registers are used up, we will report an error to notify users the compiler does not support passing scalable vector values through the stack. In this patch, we remove the restriction. After all general registers are used up, we use the stack to save the pointers which point to the indirect passed scalable vector values. Differential Revision: https://reviews.llvm.org/D116310
This commit is contained in:
parent
049cd480a0
commit
a1c7ddf926
|
@ -8393,7 +8393,8 @@ static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
|
|||
LocVT = XLenVT;
|
||||
LocInfo = CCValAssign::Indirect;
|
||||
} else if (ValVT.isScalableVector()) {
|
||||
report_fatal_error("Unable to pass scalable vector types on the stack");
|
||||
LocVT = XLenVT;
|
||||
LocInfo = CCValAssign::Indirect;
|
||||
} else {
|
||||
// Pass fixed-length vectors on the stack.
|
||||
LocVT = ValVT;
|
||||
|
@ -8592,6 +8593,12 @@ static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
|
|||
EVT LocVT = VA.getLocVT();
|
||||
EVT ValVT = VA.getValVT();
|
||||
EVT PtrVT = MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0));
|
||||
if (ValVT.isScalableVector()) {
|
||||
// When the value is a scalable vector, we save the pointer which points to
|
||||
// the scalable vector value in the stack. The ValVT will be the pointer
|
||||
// type, instead of the scalable vector type.
|
||||
ValVT = LocVT;
|
||||
}
|
||||
int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
|
||||
/*Immutable=*/true);
|
||||
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+experimental-v < %s 2>&1 | FileCheck %s
|
||||
|
||||
define <vscale x 16 x i32> @bar(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, <vscale x 16 x i32> %w, <vscale x 16 x i32> %x, <vscale x 16 x i32> %y, <vscale x 16 x i32> %z) {
|
||||
; CHECK-LABEL: bar:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: ld a0, 0(sp)
|
||||
; CHECK-NEXT: ld a1, 8(sp)
|
||||
; CHECK-NEXT: vl8re32.v v24, (a0)
|
||||
; CHECK-NEXT: vl8re32.v v0, (a1)
|
||||
; CHECK-NEXT: vsetvli a0, zero, e32, m8, ta, mu
|
||||
; CHECK-NEXT: vadd.vv v8, v8, v24
|
||||
; CHECK-NEXT: vadd.vv v16, v16, v0
|
||||
; CHECK-NEXT: vadd.vv v8, v8, v16
|
||||
; CHECK-NEXT: ret
|
||||
%s0 = add <vscale x 16 x i32> %w, %y
|
||||
%s1 = add <vscale x 16 x i32> %x, %z
|
||||
%s = add <vscale x 16 x i32> %s0, %s1
|
||||
ret <vscale x 16 x i32> %s
|
||||
}
|
||||
|
||||
define <vscale x 16 x i32> @foo(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, <vscale x 16 x i32> %x) {
|
||||
; CHECK-LABEL: foo:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -48
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 48
|
||||
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: .cfi_offset ra, -8
|
||||
; CHECK-NEXT: csrr t0, vlenb
|
||||
; CHECK-NEXT: slli t0, t0, 4
|
||||
; CHECK-NEXT: sub sp, sp, t0
|
||||
; CHECK-NEXT: addi t0, sp, 40
|
||||
; CHECK-NEXT: sd t0, 8(sp)
|
||||
; CHECK-NEXT: csrr t0, vlenb
|
||||
; CHECK-NEXT: slli t0, t0, 3
|
||||
; CHECK-NEXT: add t0, sp, t0
|
||||
; CHECK-NEXT: addi t0, t0, 40
|
||||
; CHECK-NEXT: sd t0, 0(sp)
|
||||
; CHECK-NEXT: addi t0, sp, 40
|
||||
; CHECK-NEXT: vs8r.v v8, (t0)
|
||||
; CHECK-NEXT: csrr t0, vlenb
|
||||
; CHECK-NEXT: slli t0, t0, 3
|
||||
; CHECK-NEXT: add t0, sp, t0
|
||||
; CHECK-NEXT: addi t0, t0, 40
|
||||
; CHECK-NEXT: vs8r.v v8, (t0)
|
||||
; CHECK-NEXT: vmv8r.v v16, v8
|
||||
; CHECK-NEXT: call bar@plt
|
||||
; CHECK-NEXT: csrr a0, vlenb
|
||||
; CHECK-NEXT: slli a0, a0, 4
|
||||
; CHECK-NEXT: add sp, sp, a0
|
||||
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 48
|
||||
; CHECK-NEXT: ret
|
||||
%ret = call <vscale x 16 x i32> @bar(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, <vscale x 16 x i32> %x, <vscale x 16 x i32> %x, <vscale x 16 x i32> %x, <vscale x 16 x i32> %x)
|
||||
ret <vscale x 16 x i32> %ret
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: not --crash llc -mtriple=riscv64 -mattr=+experimental-v < %s 2>&1 | FileCheck %s
|
||||
|
||||
; A rather pathological test case in which we exhaust all vector registers and
|
||||
; all scalar registers, forcing %z to go through the stack. This is not yet
|
||||
; supported, so check that a reasonable error message is produced rather than
|
||||
; hitting an assertion or producing incorrect code.
|
||||
; CHECK: LLVM ERROR: Unable to pass scalable vector types on the stack
|
||||
define <vscale x 16 x i32> @bar(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, <vscale x 16 x i32> %x, <vscale x 16 x i32> %y, <vscale x 16 x i32> %z) {
|
||||
%s = add <vscale x 16 x i32> %x, %z
|
||||
ret <vscale x 16 x i32> %s
|
||||
}
|
Loading…
Reference in New Issue