Skip to content

Commit

Permalink
[LLVM][RVV 0.7.1] Make intrinsics overloaded and try to reuse some in…
Browse files Browse the repository at this point in the history
…trinsics from the 1.0 version (#17)

* [LLVM][RVV 0.7.1] try to reuse some pseudos

* [LLVM][RVV 0.7.1] add predicates

* [LLVM][RVV 0.7.1] make `xvsetvl` and `xvsetvlmax` overloadded

* [LLVM][RVV 0.7.1] update some intrinsic tests
  • Loading branch information
imkiva authored Oct 27, 2023
1 parent 81f030f commit 1264a4b
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 125 deletions.
23 changes: 17 additions & 6 deletions llvm/include/llvm/IR/IntrinsicsRISCVXTHeadV.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@

let TargetPrefix = "riscv" in {
// 6. Configuration-Setting and Utility
def int_riscv_xvsetvl : Intrinsic<[llvm_i64_ty],
[/* AVL */ llvm_i64_ty, /* SEW */ llvm_i64_ty, /* LMUL */ llvm_i64_ty],
[IntrNoMem]>;
def int_riscv_xvsetvlmax : Intrinsic<[llvm_i64_ty],
[/* SEW */ llvm_i64_ty, /* LMUL */ llvm_i64_ty],
[IntrNoMem]>;
def int_riscv_xvsetvl : Intrinsic<[llvm_anyint_ty],
[/* AVL */ LLVMMatchType<0>,
/* SEW */ LLVMMatchType<0>,
/* LMUL */ LLVMMatchType<0>
],
[IntrNoMem,
ImmArg<ArgIndex<1>>,
ImmArg<ArgIndex<2>>
]>;
def int_riscv_xvsetvlmax : Intrinsic<[llvm_anyint_ty],
[/* SEW */ LLVMMatchType<0>,
/* LMUL */ LLVMMatchType<0>
],
[IntrNoMem,
ImmArg<ArgIndex<0>>,
ImmArg<ArgIndex<1>>
]>;

defm xvadd : RISCVBinaryAAX;

Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -924,3 +924,17 @@ def FeatureVendorXTHeadVediv
def HasVendorXTHeadVediv : Predicate<"Subtarget->hasVendorXTHeadVediv()">,
AssemblerPredicate<(all_of FeatureVendorXTHeadVediv),
"'xtheadvediv' (T-Head Divided Element Extension)">;

// Predicates for reusing instructions/intrinsics in both RVV 1.0 and 0.7
def HasStdVOrXTHeadV : Predicate<"Subtarget->hasVInstructions()">,
AssemblerPredicate<
(any_of FeatureStdExtZve32x, FeatureVendorXTHeadV),
"'V' (Vector Extension for Application Processors), 'Zve32x', "
"'Zve64x' (Vector Extensions for Embedded Processors) or"
"'XTHeadV' (Vector Extension for T-Head)">;
def HasStdVOrXTHeadVI64 : Predicate<"Subtarget->hasVInstructionsI64()">,
AssemblerPredicate<
(any_of FeatureStdExtZve64x, FeatureVendorXTHeadV),
"'V' (Vector Extension for Application Processors), 'Zve64x' "
"(Vector Extensions for Embedded Processors) or"
"'XTHeadV' (Vector Extension for T-Head)">;
6 changes: 5 additions & 1 deletion llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
Original file line number Diff line number Diff line change
Expand Up @@ -6176,7 +6176,7 @@ multiclass VPatCompare_VI<string intrinsic, string inst,
// Pseudo instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasVInstructions] in {
let Predicates = [HasStdVOrXTHeadV] in {

//===----------------------------------------------------------------------===//
// Pseudo Instructions for CodeGen
Expand All @@ -6189,6 +6189,10 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1 in {
Sched<[WriteRdVLENB]>;
}

} // Predicates = [HasStdVOrXTHeadV]

let Predicates = [HasVInstructions] in {

let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1,
Uses = [VL] in
def PseudoReadVL : Pseudo<(outs GPR:$rd), (ins), []>,
Expand Down
42 changes: 26 additions & 16 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadVPseudos.td
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,15 @@ defset list<VTypeInfo> AllXVectors = {
// 6. Configuration-Setting Instructions
//===----------------------------------------------------------------------===//

let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Defs = [VL, VTYPE] in {
def PseudoXVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, XTHeadVTypeI:$vtypei), []>,
Sched<[WriteVSETVLI, ReadVSETVLI]>;
def PseudoXVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, XTHeadVTypeI:$vtypei), []>,
// These can't be reused, since the vtypei in rvv 0.7 differs from the one in rvv 1.0
let Predicates = [HasVendorXTHeadV] in {
let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Defs = [VL, VTYPE] in {
def PseudoXVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, XTHeadVTypeI:$vtypei), []>,
Sched<[WriteVSETVLI, ReadVSETVLI]>;
}
def PseudoXVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, XTHeadVTypeI:$vtypei), []>,
Sched<[WriteVSETVLI, ReadVSETVLI]>;
}
} // Predicates = [HasVendorXTHeadV]

//===----------------------------------------------------------------------===//
// 8. Vector AMO Operations
Expand Down Expand Up @@ -153,26 +156,33 @@ multiclass XVPseudoAMO {
defm "D" : XVPseudoAMOMem<64>;
}

defm PseudoXVAMOSWAP : XVPseudoAMO;
defm PseudoXVAMOADD : XVPseudoAMO;
defm PseudoXVAMOXOR : XVPseudoAMO;
defm PseudoXVAMOAND : XVPseudoAMO;
defm PseudoXVAMOOR : XVPseudoAMO;
defm PseudoXVAMOMIN : XVPseudoAMO;
defm PseudoXVAMOMAX : XVPseudoAMO;
defm PseudoXVAMOMINU : XVPseudoAMO;
defm PseudoXVAMOMAXU : XVPseudoAMO;
let Predicates = [HasVendorXTHeadV, HasVendorXTHeadVamo, HasStdExtA] in {
defm PseudoXVAMOSWAP : XVPseudoAMO;
defm PseudoXVAMOADD : XVPseudoAMO;
defm PseudoXVAMOXOR : XVPseudoAMO;
defm PseudoXVAMOAND : XVPseudoAMO;
defm PseudoXVAMOOR : XVPseudoAMO;
defm PseudoXVAMOMIN : XVPseudoAMO;
defm PseudoXVAMOMAX : XVPseudoAMO;
defm PseudoXVAMOMINU : XVPseudoAMO;
defm PseudoXVAMOMAXU : XVPseudoAMO;
} // Predicates = [HasVendorXTHeadV, HasVendorXTHeadVamo, HasStdExtA]

// TODO: try to reuse them from RISCVInstrInfoVPseudos.td, see the `HasStdVOrXTHeadV` predicate
//===----------------------------------------------------------------------===//
// 12. Vector Integer Arithmetic Instructions
//===----------------------------------------------------------------------===//
defm PseudoXVADD : VPseudoVALU_VV_VX_VI;
let Predicates = [HasVendorXTHeadV] in {
defm PseudoXVADD : VPseudoVALU_VV_VX_VI;
} // Predicates = [HasVendorXTHeadV]

//===----------------------------------------------------------------------===//
// Patterns. Enabling code generation from intrinsics to pseudos, then to asms.
//===----------------------------------------------------------------------===//

defm : VPatBinaryV_VV_VX_VI<"int_riscv_xvadd", "PseudoXVADD", AllIntegerXVectors>;
let Predicates = [HasVendorXTHeadV] in {
defm : VPatBinaryV_VV_VX_VI<"int_riscv_xvadd", "PseudoXVADD", AllIntegerXVectors>;
} // Predicates = [HasVendorXTHeadV]

// Patterns for vamo intrinsics.
class XVPatAMOWDNoMask<string intrinsic_name,
Expand Down
105 changes: 54 additions & 51 deletions llvm/test/CodeGen/RISCV/rvv0p71/vsetvl.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+xtheadv < %s | FileCheck -check-prefix=CHECK %s
; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+xtheadv \
; RUN: -verify-machineinstrs | FileCheck %s
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+xtheadv \
; RUN: -verify-machineinstrs | FileCheck %s

; https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/v0.7.1/rvv_intrinsic_funcs/01_configuration-setting_and_utility_functions.md

Expand All @@ -13,133 +16,133 @@
; -----------------------------------
; In intrinsic, ediv is always 0 for ASM name `d1`

declare i64 @llvm.riscv.xvsetvl (i64 %avl, i64 %sew, i64 %lmul);
declare i64 @llvm.riscv.xvsetvlmax( i64 %sew, i64 %lmul);
declare iXLen @llvm.riscv.xvsetvl.iXLen (iXLen %avl, iXLen %sew, iXLen %lmul);
declare iXLen @llvm.riscv.xvsetvlmax.iXLen( iXLen %sew, iXLen %lmul);


define i64 @intrinsic_xvsetvl_e8m1(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e8m1(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e8m1
; CHECK: vsetvli a0, a0, e8, m1, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 0, i64 0)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 0, iXLen 0)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e8m2(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e8m2(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e8m2
; CHECK: vsetvli a0, a0, e8, m2, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 0, i64 1)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 0, iXLen 1)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e8m4(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e8m4(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e8m4
; CHECK: vsetvli a0, a0, e8, m4, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 0, i64 2)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 0, iXLen 2)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e8m8(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e8m8(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e8m8
; CHECK: vsetvli a0, a0, e8, m8, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 0, i64 3)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 0, iXLen 3)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e16m1(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e16m1(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e16m1
; CHECK: vsetvli a0, a0, e16, m1, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 1, i64 0)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 1, iXLen 0)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e16m2(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e16m2(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e16m2
; CHECK: vsetvli a0, a0, e16, m2, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 1, i64 1)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 1, iXLen 1)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e16m4(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e16m4(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e16m4
; CHECK: vsetvli a0, a0, e16, m4, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 1, i64 2)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 1, iXLen 2)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e16m8(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e16m8(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e16m8
; CHECK: vsetvli a0, a0, e16, m8, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 1, i64 3)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 1, iXLen 3)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e32m1(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e32m1(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e32m1
; CHECK: vsetvli a0, a0, e32, m1, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 2, i64 0)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 2, iXLen 0)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e32m2(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e32m2(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e32m2
; CHECK: vsetvli a0, a0, e32, m2, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 2, i64 1)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 2, iXLen 1)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e32m4(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e32m4(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e32m4
; CHECK: vsetvli a0, a0, e32, m4, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 2, i64 2)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 2, iXLen 2)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e32m8(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e32m8(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e32m8
; CHECK: vsetvli a0, a0, e32, m8, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 2, i64 3)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 2, iXLen 3)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e64m1(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e64m1(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e64m1
; CHECK: vsetvli a0, a0, e64, m1, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 3, i64 0)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 3, iXLen 0)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e64m2(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e64m2(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e64m2
; CHECK: vsetvli a0, a0, e64, m2, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 3, i64 1)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 3, iXLen 1)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e64m4(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e64m4(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e64m4
; CHECK: vsetvli a0, a0, e64, m4, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 3, i64 2)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 3, iXLen 2)
ret iXLen %v
}


define i64 @intrinsic_xvsetvl_e64m8(i64 %avl) {
define iXLen @intrinsic_xvsetvl_e64m8(iXLen %avl) {
; CHECK-LABEL: intrinsic_xvsetvl_e64m8
; CHECK: vsetvli a0, a0, e64, m8, d1
%v = call i64 @llvm.riscv.xvsetvl(i64 %avl, i64 3, i64 3)
ret i64 %v
%v = call iXLen @llvm.riscv.xvsetvl.iXLen(iXLen %avl, iXLen 3, iXLen 3)
ret iXLen %v
}
Loading

0 comments on commit 1264a4b

Please sign in to comment.