Skip to content

[llvm][RISCV] Support RISCV vector tuple CodeGen and Calling Convention #97995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 129 additions & 146 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
SmallVectorImpl<SDValue> &Operands,
bool IsLoad = false, MVT *IndexVT = nullptr);

void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided);
void selectVLSEGFF(SDNode *Node, bool IsMasked);
void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided);
void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
void selectVLSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
void selectVLSEGFF(SDNode *Node, unsigned NF, bool IsMasked);
void selectVLXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);
void selectVSSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsStrided);
void selectVSXSEG(SDNode *Node, unsigned NF, bool IsMasked, bool IsOrdered);

void selectVSETVLI(SDNode *Node);

Expand Down
468 changes: 427 additions & 41 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ enum NodeType : unsigned {
SF_VC_V_VVW_SE,
SF_VC_V_FVW_SE,

// RISC-V vector tuple type version of INSERT_SUBVECTOR/EXTRACT_SUBVECTOR.
TUPLE_INSERT,
TUPLE_EXTRACT,

// FP to 32 bit int conversions for RV64. These are used to keep track of the
// result being sign extended to 64 bit. These saturate out of range inputs.
STRICT_FCVT_W_RV64 = ISD::FIRST_TARGET_STRICTFP_OPCODE,
Expand Down
29 changes: 27 additions & 2 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -616,15 +616,40 @@ def GPRPair : RISCVRegisterClass<[XLenPairFVT], 64, (add
// The register class is added for inline assembly for vector mask types.
def VM : VReg<VMaskVTs, (add VR), 1>;

defvar VTupM1N2VTs = [riscv_nxv8i8x2, riscv_nxv4i8x2, riscv_nxv2i8x2, riscv_nxv1i8x2];
defvar VTupM1N3VTs = [riscv_nxv8i8x3, riscv_nxv4i8x3, riscv_nxv2i8x3, riscv_nxv1i8x3];
defvar VTupM1N4VTs = [riscv_nxv8i8x4, riscv_nxv4i8x4, riscv_nxv2i8x4, riscv_nxv1i8x4];
defvar VTupM1N5VTs = [riscv_nxv8i8x5, riscv_nxv4i8x5, riscv_nxv2i8x5, riscv_nxv1i8x5];
defvar VTupM1N6VTs = [riscv_nxv8i8x6, riscv_nxv4i8x6, riscv_nxv2i8x6, riscv_nxv1i8x6];
defvar VTupM1N7VTs = [riscv_nxv8i8x7, riscv_nxv4i8x7, riscv_nxv2i8x7, riscv_nxv1i8x7];
defvar VTupM1N8VTs = [riscv_nxv8i8x8, riscv_nxv4i8x8, riscv_nxv2i8x8, riscv_nxv1i8x8];
defvar VTupM2N2VTs = [riscv_nxv16i8x2];
defvar VTupM2N3VTs = [riscv_nxv16i8x3];
defvar VTupM2N4VTs = [riscv_nxv16i8x4];
defvar VTupM4N2VTs = [riscv_nxv32i8x2];
class VTupRegList<int LMUL, int NF> {
list<ValueType> L = !cond(!and(!eq(LMUL, 1), !eq(NF, 2)): VTupM1N2VTs,
!and(!eq(LMUL, 1), !eq(NF, 3)): VTupM1N3VTs,
!and(!eq(LMUL, 1), !eq(NF, 4)): VTupM1N4VTs,
!and(!eq(LMUL, 1), !eq(NF, 5)): VTupM1N5VTs,
!and(!eq(LMUL, 1), !eq(NF, 6)): VTupM1N6VTs,
!and(!eq(LMUL, 1), !eq(NF, 7)): VTupM1N7VTs,
!and(!eq(LMUL, 1), !eq(NF, 8)): VTupM1N8VTs,
!and(!eq(LMUL, 2), !eq(NF, 2)): VTupM2N2VTs,
!and(!eq(LMUL, 2), !eq(NF, 3)): VTupM2N3VTs,
!and(!eq(LMUL, 2), !eq(NF, 4)): VTupM2N4VTs,
!and(!eq(LMUL, 4), !eq(NF, 2)): VTupM4N2VTs);
}

foreach m = LMULList in {
foreach nf = NFList<m>.L in {
let NF = nf in {
def "VRN" # nf # "M" # m # "NoV0"
: VReg<[untyped],
: VReg<VTupRegList<m, nf>.L,
(add !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0")),
m>;
def "VRN" # nf # "M" # m
: VReg<[untyped],
: VReg<VTupRegList<m, nf>.L,
(add !cast<RegisterTuples>("VN" # nf # "M" # m # "NoV0"),
!cast<RegisterTuples>("VN" # nf # "M" # m # "V0")),
m>;
Expand Down
43 changes: 25 additions & 18 deletions llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.ll
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,33 @@ define void @_Z3foov() {
; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_40)
; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma
; CHECK-NEXT: vle16.v v8, (a0)
; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_44)
; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_44)
; CHECK-NEXT: addi a1, sp, 16
; CHECK-NEXT: csrr a2, vlenb
; CHECK-NEXT: slli a2, a2, 1
; CHECK-NEXT: vl2r.v v10, (a1) # Unknown-size Folded Reload
; CHECK-NEXT: add a1, a1, a2
; CHECK-NEXT: vl2r.v v12, (a1) # Unknown-size Folded Reload
; CHECK-NEXT: add a1, a1, a2
; CHECK-NEXT: vl2r.v v14, (a1) # Unknown-size Folded Reload
; CHECK-NEXT: add a1, a1, a2
; CHECK-NEXT: vl2r.v v16, (a1) # Unknown-size Folded Reload
; CHECK-NEXT: vle16.v v16, (a0)
; CHECK-NEXT: lui a0, 1048572
; CHECK-NEXT: addi a0, a0, 928
; CHECK-NEXT: vmsbc.vx v0, v8, a0
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: vl2r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vl2r.v v10, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vl2r.v v12, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: vl2r.v v14, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 3
; CHECK-NEXT: add a0, sp, a0
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: vl1r.v v14, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: vsetvli zero, zero, e16, m2, tu, mu
; CHECK-NEXT: vsext.vf2 v10, v8, v0.t
; CHECK-NEXT: vsext.vf2 v8, v14, v0.t
; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_44)
; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_44)
; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; CHECK-NEXT: vle16.v v14, (a0)
; CHECK-NEXT: lui a0, %hi(var_47)
; CHECK-NEXT: addi a0, a0, %lo(var_47)
; CHECK-NEXT: vsseg4e16.v v10, (a0)
; CHECK-NEXT: vsseg4e16.v v8, (a0)
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: li a1, 10
; CHECK-NEXT: mul a0, a0, a1
Expand All @@ -100,7 +101,11 @@ entry:
%8 = tail call <vscale x 8 x i1> @llvm.riscv.vmsbc.nxv8i16.i16.i64(<vscale x 8 x i16> %6, i16 -15456, i64 2)
%9 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1)
%10 = tail call <vscale x 8 x i16> @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64(<vscale x 8 x i16> %0, <vscale x 8 x i8> %1, <vscale x 8 x i1> %8, i64 2, i64 0)
tail call void @llvm.riscv.vsseg4.nxv8i16.i64(<vscale x 8 x i16> %10, <vscale x 8 x i16> %2, <vscale x 8 x i16> %3, <vscale x 8 x i16> %4, ptr nonnull @var_47, i64 2)
%v_0 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 4) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_4t.nxv8i16(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) poison, <vscale x 8 x i16> %10, i32 0)
%v_1 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 4) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_4t.nxv8i16(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %v_0, <vscale x 8 x i16> %2, i32 1)
%v_2 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 4) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_4t.nxv8i16(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %v_1, <vscale x 8 x i16> %3, i32 2)
%v_3 = call target("riscv.vector.tuple", <vscale x 16 x i8>, 4) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_4t.nxv8i16(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %v_2, <vscale x 8 x i16> %4, i32 3)
tail call void @llvm.riscv.vsseg4.nxv8i16.i64(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %v_3, ptr nonnull @var_47, i64 2, i64 4)
ret void
}

Expand All @@ -114,4 +119,6 @@ declare <vscale x 8 x i1> @llvm.riscv.vmsbc.nxv8i16.i16.i64(<vscale x 8 x i16>,

declare <vscale x 8 x i16> @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64(<vscale x 8 x i16>, <vscale x 8 x i8>, <vscale x 8 x i1>, i64, i64 immarg)

declare void @llvm.riscv.vsseg4.nxv8i16.i64(<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, ptr nocapture, i64)
declare target("riscv.vector.tuple", <vscale x 16 x i8>, 4) @llvm.riscv.tuple.insert.triscv.vector.tuple_nxv16i8_4t.nxv8i16(target("riscv.vector.tuple", <vscale x 16 x i8>, 4), <vscale x 8 x i16>, i32)

declare void @llvm.riscv.vsseg4.nxv8i16.i64(target("riscv.vector.tuple", <vscale x 16 x i8>, 4), ptr nocapture, i64, i64)
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ define void @last_chance_recoloring_failure() {
; SUBREGLIVENESS-NEXT: addi sp, sp, 32
; SUBREGLIVENESS-NEXT: ret
entry:
%i = call { <vscale x 16 x half>, <vscale x 16 x half>} @llvm.riscv.vloxseg2.nxv16f16.nxv16i32.i64( <vscale x 16 x half> undef, <vscale x 16 x half> undef, ptr nonnull poison, <vscale x 16 x i32> poison, i64 55)
%i1 = extractvalue { <vscale x 16 x half>, <vscale x 16 x half> } %i, 0
%i = call target("riscv.vector.tuple", <vscale x 32 x i8>, 2) @llvm.riscv.vloxseg2.nxv16f16.nxv16i32.i64(target("riscv.vector.tuple", <vscale x 32 x i8>, 2) undef, ptr nonnull poison, <vscale x 16 x i32> poison, i64 55, i64 4)
%i1 = tail call <vscale x 16 x half> @llvm.riscv.tuple.extract.v16f16.triscv.vector.tuple_nxv32i8_2t(target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %i, i32 0)
%i2 = call <vscale x 16 x float> @llvm.riscv.vfwadd.mask.nxv16f32.nxv16f16.nxv16f16.i64(<vscale x 16 x float> poison, <vscale x 16 x half> poison, <vscale x 16 x half> poison, <vscale x 16 x i1> zeroinitializer, i64 7, i64 36, i64 0)
call void @func()
%i3 = call <vscale x 16 x i16> @llvm.riscv.vrgather.vv.mask.nxv16i16.i64(<vscale x 16 x i16> poison, <vscale x 16 x i16> poison, <vscale x 16 x i16> poison, <vscale x 16 x i1> poison, i64 32, i64 0)
Expand All @@ -136,7 +136,8 @@ entry:
}

declare void @func()
declare { <vscale x 16 x half>, <vscale x 16 x half>} @llvm.riscv.vloxseg2.nxv16f16.nxv16i32.i64( <vscale x 16 x half>, <vscale x 16 x half>, ptr nocapture, <vscale x 16 x i32>, i64)
declare target("riscv.vector.tuple", <vscale x 32 x i8>, 2) @llvm.riscv.vloxseg2.nxv16f16.nxv16i32.i64(target("riscv.vector.tuple", <vscale x 32 x i8>, 2), ptr nocapture, <vscale x 16 x i32>, i64, i64)
declare <vscale x 16 x half> @llvm.riscv.tuple.extract.v16f16.triscv.vector.tuple_nxv32i8_2t(target("riscv.vector.tuple", <vscale x 32 x i8>, 2), i32)
declare <vscale x 16 x float> @llvm.riscv.vfwadd.mask.nxv16f32.nxv16f16.nxv16f16.i64(<vscale x 16 x float>, <vscale x 16 x half>, <vscale x 16 x half>, <vscale x 16 x i1>, i64, i64, i64 immarg)
declare <vscale x 16 x i16> @llvm.riscv.vrgather.vv.mask.nxv16i16.i64(<vscale x 16 x i16>, <vscale x 16 x i16>, <vscale x 16 x i16>, <vscale x 16 x i1>, i64, i64 immarg)
declare <vscale x 16 x float> @llvm.riscv.vfwsub.w.nxv16f32.nxv16f16.i64(<vscale x 16 x float>, <vscale x 16 x float>, <vscale x 16 x half>, i64, i64)
Expand Down
112 changes: 112 additions & 0 deletions llvm/test/CodeGen/RISCV/rvv/alloca-load-store-vector-tuple.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=riscv64 -mattr=+m,+d,+v -verify-machineinstrs \
; RUN: --riscv-no-aliases < %s | FileCheck %s

target triple = "riscv64-unknown-unknown-elf"

define target("riscv.vector.tuple", <vscale x 8 x i8>, 5) @load_store_m1x5(target("riscv.vector.tuple", <vscale x 8 x i8>, 5) %tuple) {
; CHECK-LABEL: load_store_m1x5:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -16
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 3
; CHECK-NEXT: sub sp, sp, a0
; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: vs1r.v v8, (a0)
; CHECK-NEXT: csrrs a1, vlenb, zero
; CHECK-NEXT: add a2, a0, a1
; CHECK-NEXT: vs1r.v v9, (a2)
; CHECK-NEXT: add a3, a2, a1
; CHECK-NEXT: vs1r.v v10, (a3)
; CHECK-NEXT: add a4, a3, a1
; CHECK-NEXT: vs1r.v v11, (a4)
; CHECK-NEXT: add a1, a4, a1
; CHECK-NEXT: vs1r.v v12, (a1)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: vl1re8.v v8, (a0)
; CHECK-NEXT: vl1re8.v v9, (a2)
; CHECK-NEXT: vl1re8.v v10, (a3)
; CHECK-NEXT: vl1re8.v v11, (a4)
; CHECK-NEXT: vl1re8.v v12, (a1)
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 3
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: addi sp, sp, 16
; CHECK-NEXT: jalr zero, 0(ra)
entry:
%tuple.addr = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 5), align 1
store target("riscv.vector.tuple", <vscale x 8 x i8>, 5) %tuple, ptr %tuple.addr, align 1
call void asm sideeffect "",
"~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"()
%0 = load target("riscv.vector.tuple", <vscale x 8 x i8>, 5), ptr %tuple.addr, align 1
ret target("riscv.vector.tuple", <vscale x 8 x i8>, 5) %0
}

define target("riscv.vector.tuple", <vscale x 16 x i8>, 2) @load_store_m2x2(target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %tuple) {
; CHECK-LABEL: load_store_m2x2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -16
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 2
; CHECK-NEXT: sub sp, sp, a0
; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x04, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 4 * vlenb
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: vs2r.v v8, (a0)
; CHECK-NEXT: csrrs a1, vlenb, zero
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: vs2r.v v10, (a1)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: vl2re8.v v8, (a0)
; CHECK-NEXT: vl2re8.v v10, (a1)
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 2
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: addi sp, sp, 16
; CHECK-NEXT: jalr zero, 0(ra)
entry:
%tuple.addr = alloca target("riscv.vector.tuple", <vscale x 16 x i8>, 2), align 1
store target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %tuple, ptr %tuple.addr, align 1
call void asm sideeffect "",
"~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"()
%0 = load target("riscv.vector.tuple", <vscale x 16 x i8>, 2), ptr %tuple.addr, align 1
ret target("riscv.vector.tuple", <vscale x 16 x i8>, 2) %0
}

define target("riscv.vector.tuple", <vscale x 32 x i8>, 2) @load_store_m4x2(target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %tuple) {
; CHECK-LABEL: load_store_m4x2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -16
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 3
; CHECK-NEXT: sub sp, sp, a0
; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb
; CHECK-NEXT: addi a0, sp, 16
; CHECK-NEXT: vs4r.v v8, (a0)
; CHECK-NEXT: csrrs a1, vlenb, zero
; CHECK-NEXT: slli a1, a1, 2
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: vs4r.v v12, (a1)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: vl4re8.v v8, (a0)
; CHECK-NEXT: vl4re8.v v12, (a1)
; CHECK-NEXT: csrrs a0, vlenb, zero
; CHECK-NEXT: slli a0, a0, 3
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: addi sp, sp, 16
; CHECK-NEXT: jalr zero, 0(ra)
entry:
%tuple.addr = alloca target("riscv.vector.tuple", <vscale x 32 x i8>, 2), align 1
store target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %tuple, ptr %tuple.addr, align 1
call void asm sideeffect "",
"~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"()
%0 = load target("riscv.vector.tuple", <vscale x 32 x i8>, 2), ptr %tuple.addr, align 1
ret target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %0
}
58 changes: 58 additions & 0 deletions llvm/test/CodeGen/RISCV/rvv/inline-asm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,61 @@ entry:
%0 = tail call <vscale x 1 x i1> asm "vmand.mm $0, $1, $2", "={v0},{v1},{v2}"(<vscale x 1 x i1> %in, <vscale x 1 x i1> %in2)
ret <vscale x 1 x i1> %0
}

define void @test_vector_tuple_type0(target("riscv.vector.tuple", <vscale x 8 x i8>, 3) %val, ptr %base) nounwind {
; CHECK-LABEL: test_vector_tuple_type0:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: #APP
; CHECK-NEXT: vsseg3e8.v v8, (a0)
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
entry:
tail call void asm "vsseg3e8.v $0, ($1)", "^vr,r"(target("riscv.vector.tuple", <vscale x 8 x i8>, 3) %val, ptr %base)
ret void
}

define void @test_vector_tuple_type1(target("riscv.vector.tuple", <vscale x 2 x i8>, 3) %val, ptr %base) nounwind {
; CHECK-LABEL: test_vector_tuple_type1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: #APP
; CHECK-NEXT: vsseg3e8.v v8, (a0)
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
entry:
tail call void asm "vsseg3e8.v $0, ($1)", "^vr,r"(target("riscv.vector.tuple", <vscale x 2 x i8>, 3) %val, ptr %base)
ret void
}

define void @test_vector_tuple_type2(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %val, target("riscv.vector.tuple", <vscale x 8 x i8>, 7) %val2, target("riscv.vector.tuple", <vscale x 8 x i8>, 7) %val3, ptr %base) nounwind {
; CHECK-LABEL: test_vector_tuple_type2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vl1r.v v23, (a0)
; CHECK-NEXT: csrr a2, vlenb
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v24, (a0)
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v25, (a0)
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v26, (a0)
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v27, (a0)
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v28, (a0)
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: vl1r.v v29, (a0)
; CHECK-NEXT: #APP
; CHECK-NEXT: vsseg3e8.v v8, (a1)
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: #APP
; CHECK-NEXT: vsseg7e8.v v16, (a1)
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: #APP
; CHECK-NEXT: vsseg7e8.v v23, (a1)
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
entry:
tail call void asm "vsseg3e8.v $0, ($1)", "^vr,r"(target("riscv.vector.tuple", <vscale x 16 x i8>, 4) %val, ptr %base)
tail call void asm "vsseg7e8.v $0, ($1)", "^vr,r"(target("riscv.vector.tuple", <vscale x 8 x i8>, 7) %val2, ptr %base)
tail call void asm "vsseg7e8.v $0, ($1)", "^vr,r"(target("riscv.vector.tuple", <vscale x 8 x i8>, 7) %val3, ptr %base)
ret void
}
7 changes: 3 additions & 4 deletions llvm/test/CodeGen/RISCV/rvv/regalloc-fast-crash.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@

; This test previously crashed with an error "ran out of registers during register allocation"

declare void @llvm.riscv.vsseg2.mask.nxv16i16(<vscale x 16 x i16>,<vscale x 16 x i16>, ptr, <vscale x 16 x i1>, i32)
declare void @llvm.riscv.vsseg2.mask.triscv.vector.tuple_nxv32i8_2t(target("riscv.vector.tuple", <vscale x 32 x i8>, 2), ptr, <vscale x 16 x i1>, i32, i32)

define void @test_vsseg2_mask_nxv16i16(<vscale x 16 x i16> %val, ptr %base, <vscale x 16 x i1> %mask, i32 %vl) {
define void @test_vsseg2_mask_nxv16i16(target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %val, ptr %base, <vscale x 16 x i1> %mask, i32 %vl) {
; CHECK-LABEL: test_vsseg2_mask_nxv16i16:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vmv4r.v v12, v8
; CHECK-NEXT: vsetvli zero, a1, e16, m4, ta, ma
; CHECK-NEXT: vsseg2e16.v v8, (a0), v0.t
; CHECK-NEXT: ret
entry:
tail call void @llvm.riscv.vsseg2.mask.nxv16i16(<vscale x 16 x i16> %val,<vscale x 16 x i16> %val, ptr %base, <vscale x 16 x i1> %mask, i32 %vl)
tail call void @llvm.riscv.vsseg2.mask.triscv.vector.tuple_nxv32i8_2t(target("riscv.vector.tuple", <vscale x 32 x i8>, 2) %val, ptr %base, <vscale x 16 x i1> %mask, i32 %vl, i32 4)
ret void
}
Loading
Loading